/* Image_Demo_2 © Paweî Marciniak <pmarciniak@lodz.home.pl> */
#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 struct ExecBase *SysBase;
struct Screen *Screen=NULL;
struct Window *APP_Window=NULL;

STRPTR PubScreenName="Workbench";
STRPTR APP_TitleWindow="Demo okno";
STRPTR APP_TitleScreenWindow="Demo ekran okno";

APTR  VisualInfo = NULL;

/* Opcjonalny Font */

struct TextAttr HelveticaFont13 = {
	( STRPTR )"helvetica.font", 13, 0x00, 0x00 };

struct TextAttr	HelveticaFont8 = {
	( STRPTR )"helvetica.font", 8, 0x00, 0x00 };

struct TextAttr	TopazFont8 = {
	( STRPTR )"topaz.font", 8, 0x00, 0x00 };

struct TextFont	*HelveticaFont;

/* Koniec opcjonalnego Fontu */


struct TextAttr       *Font, Attr;
WORD FontX=NULL;
WORD FontY=NULL;
UWORD OffX, OffY;

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

/* Rozmiar Okna */

	WORD Width=520;
	WORD Height=200;
	WORD MinWidth=520;
	WORD MinHeight=150;
	WORD MaxWidth=520;
	WORD MaxHeight=375;


struct NewBitMap
{
	UWORD BytesPerRow;
	UWORD Rows;
	UBYTE Flags;
	UBYTE Depth;
	UWORD pad;
	PLANEPTR Planes[8];
	LONG ColorTab[256];
	UWORD Width;
	UWORD Height;
	UWORD NumColors;
};


UBYTE chunky[]=
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,2,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,2,2,2,2,4,4,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,2,2,2,2,2,4,4,4,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,2,2,2,2,2,2,2,2,4,4,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,2,2,2,2,2,2,2,2,2,2,4,4,4,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,4,4,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,4,4,4,4,3,3,4,4,2,2,2,2,2,2,2,2,2,2,2,4,4,4,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,4,4,4,4,3,3,3,3,4,4,4,2,2,2,2,2,2,2,2,2,2,2,4,4,0,0,0,0,0,0,0,0,0,
0,0,0,0,4,4,4,4,3,3,3,3,3,3,3,4,4,2,2,2,2,2,2,2,2,2,2,2,2,4,4,0,0,0,0,0,0,0,0,
0,0,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,2,2,2,2,2,2,2,2,2,2,4,4,4,0,0,0,0,0,0,0,0,
0,6,6,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,2,2,2,2,2,2,2,2,4,4,4,4,4,4,0,0,0,0,0,0,0,
0,6,6,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,2,2,2,2,2,4,4,4,4,5,5,4,4,0,0,0,0,0,0,0,
0,0,6,6,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,2,2,2,4,4,4,4,5,5,5,5,5,4,4,0,0,0,0,0,0,
0,0,6,6,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,0,0,0,0,0,0,
0,0,0,6,6,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,0,0,0,0,0,
0,0,0,6,6,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,0,0,0,0,0,
0,0,0,0,6,6,4,4,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,0,0,0,0,
0,0,0,0,6,6,4,4,3,3,3,3,3,4,4,4,4,1,1,1,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,0,0,0,
0,0,0,0,0,6,6,4,4,3,3,4,4,4,4,1,1,1,1,1,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,0,0,0,
0,0,0,0,0,6,6,4,4,4,4,4,4,1,1,1,1,1,1,1,1,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,0,0,
0,0,0,0,0,0,6,6,4,4,4,1,1,1,1,1,1,1,1,1,1,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,6,0,
0,0,0,0,0,0,6,6,4,4,4,1,1,1,1,1,1,1,1,1,1,1,4,4,5,5,5,5,5,5,4,4,4,4,4,6,6,6,6,
0,0,0,0,0,0,0,6,6,4,4,1,1,1,1,1,1,1,1,1,1,1,4,4,4,5,5,5,5,4,4,4,4,6,6,6,6,6,6,
0,0,0,0,0,0,0,6,6,4,4,4,1,1,1,1,1,1,1,1,1,1,1,4,4,5,5,4,4,4,4,6,6,6,6,6,6,0,0,
0,0,0,0,0,0,0,0,6,6,4,4,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4,4,6,6,6,6,6,6,0,0,0,0,
0,0,0,0,0,0,0,0,6,6,4,4,4,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,6,6,6,6,6,6,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,6,6,4,4,1,1,1,1,1,1,1,1,1,4,4,4,4,6,6,6,6,6,6,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,6,6,4,4,1,1,1,1,1,1,4,4,4,4,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,6,6,4,4,1,1,1,1,4,4,4,4,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,6,6,4,4,1,4,4,4,4,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,6,6,4,4,4,4,4,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,6,6,4,4,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};

UBYTE Palette[]={ 0, 0, 0,
								 0, 255, 0,
								 255, 0, 0,
								 255, 255, 0,
								 255, 255, 255,
								 0, 0, 255,
								 127, 127, 127 };


struct ChunkyImg chunkyimg;

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


void ShowText( STRPTR text )
{
	SetAPen( APP_Window->RPort, 1 );
	SetDrMd( APP_Window->RPort, JAM2 );
	Move( APP_Window->RPort, 20, 384);
	Text( APP_Window->RPort, text, (ULONG)strlen( text ) );
}

/* Funkcja otwiera okreôlony (Helvetica 8 lub 13) */
/* font w zaleûnoôci od zmiennej DisplayLace      */

int OpenFonts( int DisplayLace )
{
	if( DisplayLace )
	{
		if (!(HelveticaFont=OpenDiskFont( &HelveticaFont13 )))
		{
			HelveticaFont=OpenDiskFont( &TopazFont8 );
			return( FALSE );
		}
	}
	else
	{
		if (!(HelveticaFont=OpenDiskFont( &HelveticaFont8 )))
		{
			HelveticaFont=OpenDiskFont( &TopazFont8 );
			return( FALSE );
		}
	}
	return( TRUE );
}


/* Funkcja zamyka otwarty font */

void CloseFonts( void )
{
	if ( HelveticaFont )	
	{
		CloseFont( HelveticaFont );
		HelveticaFont=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 = &Attr;
	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;

	if (( ComputeX( Width ) + OffX + Screen->WBorRight ) > Screen->Width )
	{
		Font->ta_Name = (STRPTR)"topaz.font";
		FontX = FontY = Font->ta_YSize = 8;
	}
	if (( ComputeY( Height ) + OffY + Screen->WBorBottom ) > Screen->Height )
	{
		Font->ta_Name = (STRPTR)"topaz.font";
		FontX = FontY = Font->ta_YSize = 8;
	}
	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_MinHeight,		OffY,
		WA_MinWidth,		(ComputeX(Width) + OffX + Screen->WBorRight),
		WA_MaxHeight,		(ComputeY(Height) + OffY + Screen->WBorBottom),
		WA_MaxWidth,		(ComputeX(Width) + OffX + Screen->WBorRight),
		WA_Title,				APP_TitleWindow,
		WA_ScreenTitle,	APP_TitleScreenWindow,
		WA_Flags,				WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SIZEGADGET | WFLG_SMART_REFRESH | WFLG_HASZOOM,
		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 );

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

	ComputeFont();

	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 ( !(ImageBase = (struct Library *) OpenLibrary((UBYTE *) "image.library" , 36 )))
	{
		printf("error\n");
		return( FALSE );
	}
	if ( !(DiskFontBase = (struct Library *) OpenLibrary((UBYTE *) "diskfont.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;
struct BitMap *BM;
struct BitMap *DestBM;
struct Image MyImage;

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

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

	SetAPen( APP_Window->RPort, 1 );
	ShowText("Chunky to BitMap please wait...           ");

	chunkyimg.ci_Width=39;
	chunkyimg.ci_Height=38;
	chunkyimg.ci_NumColors=7;
	chunkyimg.ci_Palette=Palette;
	chunkyimg.ci_ChunkyData=chunky;
	BM = ChunkyToBitMap( Screen, &chunkyimg, TAG_DONE);

	ShowText("Displaing BitMap please wait...        ");

	DrawBitMap( BM, 20, 20, 39, 38, APP_Window->RPort );

	ShowText("Drawing Text please wait...             ");

	DrawText( DT_Texts,"1bimage.library\n© 1993 Paweî Marciniak\ne-mail <pmarciniak@lodz.home.pl>\n\
Idea i programowanie\n1Paweî Marciniak",
 DT_FontA, HelveticaFont,
 DT_FontB, HelveticaFont,
 DT_RastPort , APP_Window->RPort,
 DT_Top, 40,
 DT_Left, 200,
 TAG_DONE);

	ShowText("Drawing 3DBox please wait...                 ");

	Draw3DBox( APP_Window->RPort, HelveticaFont,
						DBA_PosX,		80,
						DBA_PosY,		30,
						DBA_Width,	240,
						DBA_Height,	100,
						DBA_Text,		"Draw3DBox",
            DBA_Align,  ALIGN_CENTER,
						TAG_DONE );

	ShowText("Scaling BitMap please wait...                 ");

	if(DestBM = ScaleBitMap( BM,
										SBA_SrcWidth, 39,
										SBA_SrcHeight, 38,
										SBA_DestWidth, 39,
										SBA_DestHeight, 70,
										TAG_DONE))
	{
		DrawBitMap( DestBM, 340, 20, 39, 70, APP_Window->RPort );
		FreeBitMap( DestBM );
	}

	MyImage.LeftEdge = 0;
	MyImage.TopEdge = 0;
	MyImage.Width = 39;
	MyImage.Height = 38;
	MyImage.Depth = Screen->RastPort.BitMap->Depth;
	MyImage.ImageData = BM->Planes[0];
	MyImage.PlanePick = 255;
	MyImage.PlaneOnOff = 0;
	MyImage.NextImage = 0;

	DrawImage( APP_Window->RPort, &MyImage, 340, 100 );

	ShowText("That's all folks                                    ");

	do
	{
		WaitPort( APP_Window->UserPort );

		while ( ReadIMsg( APP_Window ))
		{
			switch ( IClass )
			{
				case	IDCMP_REFRESHWINDOW:
					GT_BeginRefresh( APP_Window );
					DrawBitMap( BM, 20, 20, 39, 38, APP_Window->RPort );
					GT_EndRefresh( APP_Window, TRUE );
					break;

				case	IDCMP_CLOSEWINDOW:
					FreeChunky( Screen, BM );
					running=FALSE;

					break;
						
				default:
				break;
			}
		}
	} while ( running );

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