/* Image_Demo © Paweî Marciniak */
/* Obrazek pochodzi z pîyty MACD 2 */
#include <stdio.h>
#include <string.h>
#include <exec/execbase.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <graphics/scale.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/diskfont.h>
#include <proto/dos.h>
#include <stdlib.h>
#include <time.h>

#include <proto/image.h>
#include <libraries/image.h>

#include "APP_globals.h"

extern UBYTE home_pal[];
extern UBYTE __far home_data[];

extern struct ExecBase *SysBase;
struct Screen *Screen=NULL;
struct Window *APP_Window=NULL;

STRPTR PubScreenName="Workbench";
STRPTR APP_TitleWindow="Image.library Demo Window";
STRPTR APP_TitleScreenWindow="Image.library Demo Screen";

APTR  VisualInfo = NULL;

/* Font */

struct TextAttr *Font, ScreenFont;
struct TextFont	*APP_Font;

WORD FontX=NULL;
WORD FontY=NULL;
UWORD OffX, OffY;

ULONG			IClass;
UWORD			Code, Qualifier;
struct Gadget	*IObject;

/* Rozmiar Okna */

	WORD Width=320;
	WORD Height=150;
	WORD MinWidth=50;
	WORD MinHeight=30;
	WORD MaxWidth=1600;
	WORD MaxHeight=1200;

	struct ChunkyImg homeimg;


/* Tytaj zaczynajâ sië wszystkie poûyteczne funkcje */


/* Funkcja otwiera okreôlony font */

int OpenFonts( void )
{
	if (!(APP_Font=OpenDiskFont( &ScreenFont )))
		return( FALSE );
	return( TRUE );
}


/* Funkcja zamyka otwarty font */

void CloseFonts( void )
{
	if ( APP_Font )	
	{
		CloseFont( APP_Font );
		APP_Font=NULL;
	}
}


UWORD ComputeX( UWORD value )
{
	return(( UWORD )((( FontX * value ) + 4 ) / 8 ));
}


UWORD ComputeY( UWORD value )
{
	return(( UWORD )((( FontY * value ) + 4 ) / 8 ));
}


void ComputeFont( void )
{
	Font = &ScreenFont;
	Font->ta_Name = (STRPTR)Screen->RastPort.Font->tf_Message.mn_Node.ln_Name;
	Font->ta_YSize = FontY = Screen->RastPort.Font->tf_YSize;
	FontX = Screen->RastPort.Font->tf_XSize;

	OffX = Screen->WBorLeft;
	OffY = Screen->RastPort.TxHeight + Screen->WBorTop + 1;
	return;
}


/* Funkcja otwiera okno */

int OpenAPP_Display( WORD Left, WORD Top )
{

	if(!(APP_Window=OpenWindowTags( 0,
		WA_Left,				Left,
		WA_Top,					Top,
		WA_Width,				(ComputeX(Width) + OffX + Screen->WBorRight),
		WA_Height,			(ComputeY(Height) + OffY + Screen->WBorBottom),
		WA_MinWidth,		(ComputeX(MinWidth) + OffX + Screen->WBorRight),
		WA_MinHeight,		(ComputeX(MinHeight) + OffY + Screen->WBorBottom),
		WA_MaxWidth,		(ComputeX(MaxWidth) + OffX + Screen->WBorRight),
		WA_MaxHeight,		(ComputeY(MaxHeight) + OffY + Screen->WBorBottom),
		WA_Title,				APP_TitleWindow,
		WA_ScreenTitle,	APP_TitleScreenWindow,
		WA_Flags,				WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEGADGET | WFLG_CLOSEGADGET | WFLG_SIMPLE_REFRESH,
		WA_IDCMP,				IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW,
		WA_Gadgets,			FALSE,
		WA_AutoAdjust,	FALSE,
		WA_PubScreen,		(struct Screen *)Screen,
		TAG_DONE)))
			return( FALSE );
	GT_RefreshWindow( APP_Window, NULL );
	return( TRUE );
}


/* Funkcja zamyka otwarte okno */

void CloseAPP_Display(void)
{
	if(APP_Window) 
	{
		CloseWindow((struct Window *)APP_Window);
		APP_Window=NULL;
	}
}


/* Funkcja odczytuje komunikat Intuition */

LONG ReadIMsg( struct Window *iwnd )
{
	struct IntuiMessage *imsg;

	if ( imsg = GT_GetIMsg( iwnd->UserPort ))
        {
		IClass	  =	imsg->Class;
		Qualifier	=	imsg->Qualifier;
		Code		=	imsg->Code;
		IObject	 =	imsg->IAddress;

		GT_ReplyIMsg( imsg );

		return( TRUE );
	}
	return( FALSE );
}


/* Funkcja alokuje ekran */

int SetupScreen( void )
{
	if (!(Screen = LockPubScreen( PubScreenName )))
		return( FALSE );

	ComputeFont();

	if(!(OpenFonts()))
		return( FALSE );


	if (!( VisualInfo = GetVisualInfo( Screen, TAG_DONE )))
		return( FALSE );

	return( TRUE );
}


/* Funkcja dealokuje ekran */

void CloseDownScreen( void )
{
	if ( VisualInfo )
	{
		FreeVisualInfo( VisualInfo );
		VisualInfo = NULL;
	}

	CloseFonts();

	if ( Screen )
	{
		UnlockPubScreen( NULL, Screen );
		Screen = NULL;
	}
}


/* Funkcja otwiera wszystkie biblioteki */

LONG OpenLibraries( void )
{
	if ( !(DosBase = (struct DosLibrary *) OpenLibrary((UBYTE *) "dos.library", 36 )))
		return( FALSE );
	if ( !(IntuitionBase = (struct IntuitionBase *) OpenLibrary((UBYTE *) "intuition.library", 36 )))
		return( FALSE );
	if ( !(GadToolsBase = (struct Library *) OpenLibrary((UBYTE *) "gadtools.library", 36 )))
		return( FALSE );
	if ( !(GfxBase = (struct GfxBase *) OpenLibrary((UBYTE *) "graphics.library" , 36 )))
		return( FALSE );
	if ( !(DiskFontBase = (struct Library *) OpenLibrary((UBYTE *) "diskfont.library" , 36 )))
		return( FALSE );
	if ( !(ImageBase = (struct Library *) OpenLibrary((UBYTE *) "image.library" , 36 )))
		return( FALSE );
	return( TRUE );
}


/* Funkcja zamyka wszystkie biblioteki */

void CloseLibraries( void )
{
	if (ImageBase)			CloseLibrary( (struct Library *) ImageBase );
	if (DiskFontBase)		CloseLibrary( (struct Library *) DiskFontBase );
	if (GfxBase)				CloseLibrary( (struct Library *) GfxBase );
	if (GadToolsBase)		CloseLibrary( (struct Library *) GadToolsBase );
	if (IntuitionBase)	CloseLibrary( (struct Library *) IntuitionBase );
	if (DosBase)				CloseLibrary( (struct Library *) DOSBase );
}



/* Gîówna funkcja */

int main( int argc, char *argv[] )
{
BOOL running=TRUE;
UBYTE text[50];
struct BitMap *HomeBM, *ScaledBM;

	if(!(OpenLibraries()))
	{
		CloseLibraries();
		return( FALSE );
	}
	
	if(!(SetupScreen()))
	{
		CloseDownScreen();
		CloseLibraries();
		return( FALSE );
	}

	if(!(OpenAPP_Display( 20, 20 )))
	{
		CloseDownScreen();
		CloseLibraries();
		return( FALSE );
	}

	SetWindowTitles( APP_Window, "Converce c2p wait...", (UBYTE *)~0 );
	homeimg.ci_Width=640;
	homeimg.ci_Height=512;
	homeimg.ci_NumColors=128;
	homeimg.ci_Palette=home_pal;
	homeimg.ci_ChunkyData=home_data;
	if(!(HomeBM = ChunkyToBitMap( Screen, &homeimg, CTBM_Precision, PRECISION_EXACT, TAG_DONE)))
	{
		CloseAPP_Display();
		CloseDownScreen();
		CloseLibraries();
		return( TRUE );
	}
	SetWindowTitles( APP_Window, "Scaling...", (UBYTE *)~0 );
	if(ScaledBM = ScaleBitMap( HomeBM,
										SBA_SrcWidth, 640,
										SBA_SrcHeight, 512,
										SBA_DestWidth, (APP_Window->Width - (OffX + APP_Window->BorderRight)),
										SBA_DestHeight, (APP_Window->Height - (OffY + APP_Window->BorderBottom)),
										TAG_DONE))
	{
		SetWindowTitles( APP_Window, "Drawing...", (UBYTE *)~0 );
		DrawBitMap( ScaledBM, OffX, OffY, (APP_Window->Width - (OffX + APP_Window->BorderRight)), (APP_Window->Height - (OffY + APP_Window->BorderBottom)), APP_Window->RPort );
		FreeBitMap( ScaledBM );
		sprintf(text,"Image size: %dx%d", (APP_Window->Width - (OffX + APP_Window->BorderRight)), (APP_Window->Height - (OffY + APP_Window->BorderBottom)));
		SetWindowTitles( APP_Window, text, (UBYTE *)~0 );
	}
	

	do
	{
		WaitPort( APP_Window->UserPort );

		while ( ReadIMsg( APP_Window ))
		{
			switch ( IClass )
			{
				case	IDCMP_REFRESHWINDOW:
					GT_BeginRefresh( APP_Window );
					GT_EndRefresh( APP_Window, TRUE );
					SetWindowTitles( APP_Window, "Scaling...", (UBYTE *)~0 );
					if(ScaledBM = ScaleBitMap( HomeBM,
										SBA_SrcWidth, 640,
										SBA_SrcHeight, 512,
										SBA_DestWidth, (APP_Window->Width - (OffX + APP_Window->BorderRight)),
										SBA_DestHeight, (APP_Window->Height - (OffY + APP_Window->BorderBottom)),
										TAG_DONE))
					{
						SetWindowTitles( APP_Window, "Drawing...", (UBYTE *)~0 );
						DrawBitMap( ScaledBM, OffX, OffY, (APP_Window->Width - (OffX + APP_Window->BorderRight)), (APP_Window->Height - (OffY + APP_Window->BorderBottom)), APP_Window->RPort );
						FreeBitMap( ScaledBM );
						sprintf(text,"Image size: %dx%d", (APP_Window->Width - (OffX + APP_Window->BorderRight)), (APP_Window->Height - (OffY + APP_Window->BorderBottom)));
						SetWindowTitles( APP_Window, text, (UBYTE *)~0 );
					}
				break;

				case	IDCMP_CLOSEWINDOW:
					running=FALSE;
					FreeChunky( Screen, HomeBM );
					break;
						
				default:
				break;
			}
		}
	} while ( running );

	CloseAPP_Display();
	CloseDownScreen();
	CloseLibraries();
	return( TRUE );
}
