/*------------------------------------------------------------------------

$Workfile:   ROT13.CL  $

$Header: /cvs/sc/sc/addin/rot13/rot13.cl,v 1.1.1.1 2000/09/18 16:44:46 hr Exp $

Description:    StarCalc ROT13 AddIn Example

(c) Copyright 1998 - 2000, Sun Microsystems, Inc.

------------------------------------------------------------------------*/

static char rot13_Id[]="@(#) StarCalc Rot13 AddIn (c) 1998-2000 Sun Microsystems, Inc.";

#include <string.h>
#include <stdio.h>

#include <xlang.h>
#include <addin.h>
#include <rot13.hrc>

/**
 * the current language the Addin is using
 */
static USHORT _nLanguage=LANGUAGE_ENGLISH;


/**
 * Get text resource for current language.
 * Remember that 8-bit characters are shown in
 * system dependend code pages!
 * To get correct results you will have to distuinguish
 * for example between UNIX and WIN and OS2 target systems.
 */
static char* getText( int nResource )
{
	switch( nResource ) {
		case ROT13_DESC:
			switch( _nLanguage ) {
				case LANGUAGE_GERMAN:
				return( "ROT13 Algorithmus, jedes alphabetische Zeichen des Textes wird um 13 im Alphabet rotiert." );
				case LANGUAGE_ENGLISH:
				default:
				return( "ROT13 Algorithm, each alphabetical character of the text is rotated by 13 in the alphabet");
			}
			break;
		case ROT13_PAR1_NAME:
			switch( _nLanguage ) {
				case LANGUAGE_GERMAN:
				return( "Text" );
				case LANGUAGE_ENGLISH:
				default:
				return( "Text");
			}
			break;
		case ROT13_PAR1_DESC:
			switch( _nLanguage ) {
				case LANGUAGE_GERMAN:
				return( "Der Text der rotiert werden soll" );
				case LANGUAGE_ENGLISH:
				default:
				return( "The text that is to be rotated");
			}
			break;
		default:
			break;
	}
	return("");
}


/**
 * Get neutral language for specific language.
 * This simplifies the getText switch cases and allows to handle
 * previously unknown language derivates due to foreign installations.
 * If you want to distinguish between some dialects change this function
 * to return the desired nLang before doing the bit masking stuff.
 * See xlang.h for defined LANGUAGE_*
 */
static USHORT GetNeutralLanguage( USHORT nLang )
{
	USHORT nPrimLang;

	/* ignore LANGUAGE_USER* */
	if ( (nLang & 0x03FF) >= 0x0200 )
		return nLang;

	nLang &= 0x03FF;

	nPrimLang = nLang | 0x0400;

	switch ( nPrimLang )
	{
		case LANGUAGE_CHINESE_TRADITIONAL:
			nLang = LANGUAGE_CHINESE;
			break;
		case LANGUAGE_ENGLISH_US:
			nLang = LANGUAGE_ENGLISH;
			break;
		case LANGUAGE_NORWEGIAN_BOKMAL:
			nLang = LANGUAGE_NORWEGIAN;
			break;
		case LANGUAGE_PORTUGUESE_BRAZILIAN:
			nLang = LANGUAGE_PORTUGUESE;
			break;

		default:
			nLang = nPrimLang;
			break;
	}

	return nLang;
}


/**
 * StarCalc calls this function to set a new current Language for the Addin
 *
 * @param *nLanguage
 *
 */
void CALLTYPE SetLanguage( USHORT* nLanguage )
{
	_nLanguage = GetNeutralLanguage( *nLanguage );
}


/**
 * Tell StarCalc how many new functions this Addin provides.
 *
 * @param *nCount - returns the number of functions which are exported to StarCalc
 *
 */
void CALLTYPE GetFunctionCount( USHORT *nCount )
{
    *nCount = 1;
}

/**
 * Provides neccessary data for each new function to StarCalc
 *
 * @param *nNo Input: Function number between 0 and nCount - 1
 * @param *pFuncName Output: Functionname which should be called in the AddIn-DLL
 * @param *nParamCount Output: Number of Parameter. Must be greater than 0, because there's always a return-Value. Maximum is 16.
 * @param *peType Output: Pointer to arrray with exactly 16 variables of typ Paramtype. nParamCount Entries are set to the type of the corresponding Parameters.
 * @param *pInternalName Output: Functionname as seen by the Spreadsheet user
 *
 * @see #GetFunctionCount, #GetParameterDescription
 *
 */
void CALLTYPE GetFunctionData( USHORT *    nNo,
			       char *      pFuncName,
			       USHORT *    nParamCount,
			       ParamType * peType,
			       char *      pInternalName )
{

    switch( *nNo ) {
	case 0:
	    /* the function name is the same in all languages */
	    SO_StringCopy( pInternalName, "Rot13" );
	    SO_StringCopy( pFuncName,     "Rot13" );
	    peType[0] = PTR_STRING;
	    peType[1] = PTR_STRING;
	    *nParamCount=2;
	    break;
	 default:
	    *nParamCount    = 0;
	    *pFuncName     = 0;
	    *pInternalName = 0;
	    break;
    }
}

/**
 * Provides descriptions for each new function to StarCalc
 * which are shown is the autopilot
 *
 * @param *nNo Input Parameter, Function number between 0 and nCount - 1
 * @param *nParam Parameter Number
 * @param *pName Output: Name of the parameter
 * @param *pDesc Output: Description of the parameter
 *
 * @see #GetFunctionCount, #GetParameterDescription
 */
void CALLTYPE GetParameterDescription( USHORT* nNo, USHORT* nParam,
char* pName, char* pDesc )
{
	*pName = 0;
	*pDesc = 0;


	switch ( *nNo ) {
	case 0:
		switch ( *nParam ) {
		case 0:
			SO_StringCopy(pDesc,getText(ROT13_DESC));
			break;
		case 1:
			SO_StringCopy(pName,getText(ROT13_PAR1_NAME));
			SO_StringCopy(pDesc,getText(ROT13_PAR1_DESC));
		}
	}
}

/**
 * ROT13 Algorithm, each alphabetical character of the text is rotated by 13 in the alphabet
 *
 * @param *ret
 * @param *src
 *
 * ER: well, my personal favorite algorithm is
 * main(_){while(_=~getchar())putchar(~_-1/(~(_|32)/13*2-11)*13);}
 * but for clarification we do it somehow different here ;-)
 */
void CALLTYPE Rot13(char *ret, char *src)
{
    if ( ! ret ) return;
    if ( ! src ) *ret='\0';

    for(;src && *src; src++ , ret++) {
	*ret=*src;
	if (*ret >= 'A' && *ret <= 'Z') {
	    if ( (*ret +=13) > 'Z' ) *ret-=26;
	} else if (*ret >= 'a' && *ret < 'n') {
	    *ret +=13;
	} else if (*ret >= 'n' && *ret <= 'z') {
	    *ret -=13;
	}
    }
    *ret=*src;
}




