/* quickhelp_lib.c © Copyright Paweî Marciniak 1996. */
#include <string.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/locale.h>
#include <graphics/text.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/diskfont.h>
#include <clib/exec_protos.h>
#include <clib/locale_protos.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/locale_pragmas.h>
#include <utility/tagitem.h>
#include <proto/utility.h>

#include	"include/clib/QuickHelp_protos.h"

int __saveds __UserLibInit( VOID );
void __saveds __UserLibCleanup( VOID );

extern struct ExecBase	*SysBase;
struct GfxBase					*GfxBase;
struct IntuitionBase		*IntuitionBase;
struct Library					*UtilityBase;
struct Window						*HelpWindow;

struct Locale		*locale;
struct Catalog	*catalog;
struct Library	*LocaleBase;

STRPTR errstr=NULL;

/* Komunikaty o bîëdach */
STRPTR ERR_MSG_TOOMANY="Too many new line chars";
STRPTR ERR_MSG_NOCATALOG="Couldn't open QuickHelp_lib.catalog";
STRPTR ERR_MSG_NOLOCALE="Couldn't open locale.library";
STRPTR ERR_MSG_STRLENNULL="No text";
STRPTR ERR_MSG_NOMEM="Couldn't alloc memory for text";
STRPTR ERR_MSG_STRTOOLONG="Longest text is too long";
STRPTR ERR_MSG_NOHELPWIN="Couldn't open help window";

STRPTR verstr="\0$VER: quickhelp.library 37.03 ("__AMIGADATE__" "__TIME__")";
STRPTR overstr="QuickHelp © Paweî Marciniak 1996-1999";

/* definicja tagów */

#define OH_Dummy	(TAG_USER + 1)

#define OH_PozX			(OH_Dummy + 0x01)
#define OH_PozY			(OH_Dummy + 0x02)

int __saveds __UserLibInit( VOID )
{
	int retval = 1;

  if (GfxBase = OpenLibrary( "graphics.library", 37L ))
  {
		if (IntuitionBase = OpenLibrary( "intuition.library", 37L ))
    {
    	if (UtilityBase = OpenLibrary( "utility.library", 37L )) 
    	{
				retval = 0;
			}
		}
	}
	if(LocaleBase=OpenLibrary("locale.library",38))
	{
		if(catalog=OpenCatalog(NULL, "quickhelp_lib.catalog",   
							OC_BuiltInLanguage, "english", TAG_DONE))
		{
			ERR_MSG_TOOMANY=GetCatalogStr(catalog, 1002, ERR_MSG_TOOMANY);
			ERR_MSG_STRLENNULL=GetCatalogStr(catalog, 1003, ERR_MSG_STRLENNULL);
			ERR_MSG_NOMEM=GetCatalogStr(catalog, 1004, ERR_MSG_NOMEM);
			ERR_MSG_STRTOOLONG=GetCatalogStr(catalog, 1005, ERR_MSG_STRTOOLONG);
			ERR_MSG_NOHELPWIN=GetCatalogStr(catalog, 1006, ERR_MSG_NOHELPWIN);
		}
		else
			errstr=ERR_MSG_NOCATALOG;
	}
	else
		errstr=ERR_MSG_NOLOCALE;
  return( retval );
}


VOID __saveds __UserLibCleanup( VOID )
{
	if(catalog)				CloseCatalog( catalog );
	if(LocaleBase)		CloseLibrary( LocaleBase );
	if(UtilityBase)		CloseLibrary( UtilityBase );
	if(GfxBase)				CloseLibrary( (struct Library *) GfxBase );
	if(IntuitionBase)	CloseLibrary( (struct Library *) IntuitionBase );
}

/* Funkcja OpenHelp (c) Paweî Marciniak 1996 */
BOOL __saveds __asm LIBOpenHelpA(register __a0 STRPTR texts,
																register __a1 struct TextFont *TxFont,
																register __a2 struct Window *APP_Window,
																register __a3 struct TagItem *Tags)
{
	STRPTR text=NULL;
	APTR mem=NULL;
	char *adresy[10]; /* Adresy poszczególnych tekstów */

	WORD WinWidth;
	WORD WinHeight;
	WORD WinLeft = -1;
	WORD WinTop = -1;
	WORD factor=8;
	struct TagItem *ti, *TagsTmp;

	register int licznik=0;
	register int loop=0, new=0, old=0, numtab=0;

  if(!strlen(texts))
  {
  	errstr=ERR_MSG_STRLENNULL;
    return FALSE;
   }
/* Alokujemy pamiëę dla tekstu */
	if(!(text=AllocVec( (strlen(texts)+1), MEMF_ANY )))
	{
		errstr=ERR_MSG_NOMEM;
		return FALSE;
	}
	mem=(APTR)text;
/* Kopiujemy "texts" do naszej pamiëci "text" */
	strcpy(text, texts);
/* Wpisujemy adres pierwszego tekstu do tablicy */
	adresy[licznik]=text;
/* Zamieniamy wszystkie znaki "\n" na "\0", */
/* i wpisujemy ich adresy do tablicy adresy */
	while(*text != '\0')
	{
		if(*text == '\n')
		{
			*text='\0';
			licznik++;
			text++;
			if(licznik==10)
      {
				FreeVec(mem);
				mem=NULL;
				errstr=ERR_MSG_TOOMANY;
				return FALSE;
      }
      else
				adresy[licznik]=text;
		}
		else
			text++;
	}

/* Szukamy i obliczamy dîugoôę najdîuűszego tekstu */
  while(loop <= licznik)
  {
  	new=strlen(adresy[loop]);
  	if(new > old)
  	{
			old=new;
  		numtab=loop;
		}
	  loop++;
  }

	TagsTmp = Tags;
	while ( ti = NextTagItem( &TagsTmp ) )
	{
		switch ( ti->ti_Tag )
		{
			case OH_PozX:
				WinLeft = ti->ti_Data;
			break;
			
			case OH_PozY:
				WinTop = ti->ti_Data;
			break;
			
			default:
			break;
		}
	}


/* Obliczamy rozmiar okna pomocy */
	WinHeight=((TxFont->tf_YSize) * (licznik+1)) + factor;
	WinWidth=TextLength(APP_Window->RPort, adresy[numtab], strlen(adresy[numtab]));
	WinWidth+=(((factor*2)*APP_Window->WScreen->Width)/640);
	if( WinLeft == -1 || WinTop == -1 )
	{
		WinTop=APP_Window->WScreen->MouseY+(APP_Window->WScreen->RastPort.TxHeight + APP_Window->WScreen->WBorTop);
		WinLeft=APP_Window->WScreen->MouseX-(WinWidth/2);
	}
	if(WinWidth > APP_Window->WScreen->Width)
	{
		FreeVec(mem);
		mem=NULL;
		errstr=ERR_MSG_STRTOOLONG;
		return FALSE;
	}
/* Otwieramy okno */
	if(HelpWindow=OpenWindowTags(0,
					WA_Left, WinLeft,
					WA_Top, WinTop,
					WA_Width, WinWidth,
					WA_Height, WinHeight,
					WA_Flags, WFLG_BORDERLESS,
					WA_AutoAdjust,	TRUE,
					WA_Activate,	FALSE,
					WA_CustomScreen, APP_Window->WScreen,
					TAG_END))
	{
	/* Wypeîniamy okna */
		SetAPen(HelpWindow->RPort, 2);
		RectFill(HelpWindow->RPort, 0, 0, WinWidth-1, WinHeight-1);
	/* Ustawiamu font */
		SetFont(HelpWindow->RPort,TxFont);
	/* i kolory dla fontu */
		SetAPen(HelpWindow->RPort, 1);
		SetBPen(HelpWindow->RPort, 2);
	/* Piszemy nasze tekst */
		loop=0;
	  while(loop <= licznik)
  	{
			Move(HelpWindow->RPort, (WinWidth-(TextLength(APP_Window->RPort, adresy[loop], strlen(adresy[loop]))))/2, ((HelpWindow->RPort->TxBaseline)+((TxFont->tf_YSize)*loop))+((((factor))))/2);
			Text(HelpWindow->RPort, adresy[loop], strlen(adresy[loop]));
			loop++;
		}
	/* Rysujemy ramki */
		Move(HelpWindow->RPort, 0 , 0);
		Draw(HelpWindow->RPort, 0, WinHeight-1);
		Draw(HelpWindow->RPort, WinWidth-1, WinHeight-1);
		Draw(HelpWindow->RPort, WinWidth-1, 0);
		Draw(HelpWindow->RPort, 0, 0);
		if(mem)	FreeVec(mem);
		mem=NULL;
		return TRUE;
	}
	errstr=ERR_MSG_NOHELPWIN;
	return FALSE;
}

/* Funkcja CloseHelp (C) Paweî Marciniak 1996 */
VOID __saveds __asm  LIBCloseHelp( VOID )
{
	if(HelpWindow)
		CloseWindow(HelpWindow);
	HelpWindow=NULL;
}

/* Funkcja GetQuickHelpString (C) Paweî Marciniak 1997 */
STRPTR __saveds __asm LIBGetQuickHelpString( VOID )
{
	return( errstr );
}
