/* 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 HAM 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;

UBYTE hammode;

/* Rozmiar Okna */

  WORD Width=320;
  WORD Height=150;
  WORD MinWidth=50;
  WORD MinHeight=30;
  WORD MaxWidth=654;
  WORD MaxHeight=511;

  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,   (ComputeY(MinHeight) + OffY + Screen->WBorBottom),
    WA_MaxWidth,    (MaxWidth + OffX + Screen->WBorRight),
    WA_MaxHeight,   (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;

  if(!(OpenLibraries()))
  {
    printf("OpenLibraries failed\n");
    CloseLibraries();
    return( FALSE );
  }
  
  if(!(SetupScreen()))
  {
    printf("Can't lock screen\n");
    CloseDownScreen();
    CloseLibraries();
    return( FALSE );
  }

/* Sprawdzamy czy ekran jest w trybie HAM */
  if( Screen->ViewPort.Modes & HAM )
  {
    if( Screen->BitMap.Depth == 6 )
    {
      printf("HAM6 mode\n");
      hammode=MODE_HAM6;
    }
    if( Screen->BitMap.Depth == 8 )
    {
      printf("HAM8 mode\n");
      hammode=MODE_HAM8;
    }
  }
  else
  {
    printf("I need HAM screen\n");
    CloseDownScreen();
    CloseLibraries();
    return( FALSE );
  }


  if(!(OpenAPP_Display( 20, 20 )))
  {
    printf("Can't open window\n");
    CloseDownScreen();
    CloseLibraries();
    return( FALSE );
  }

  SetWindowTitles( APP_Window, "Converce c2h 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 = ChunkyToHAM( &homeimg, CTBH_HamMode, hammode, TAG_DONE)))
  {
    printf("ChunkyToHAM failed - no mem\n");
    CloseAPP_Display();
    CloseDownScreen();
    CloseLibraries();
    return( TRUE );
  }
  SetWindowTitles( APP_Window, "Drawing...", (UBYTE *)~0 );
  DrawBitMap( HomeBM, OffX, OffY, (APP_Window->Width - (OffX + APP_Window->BorderRight)), (APP_Window->Height - (OffY + APP_Window->BorderBottom)), APP_Window->RPort );
  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:
          SetWindowTitles( APP_Window, "Refreshing...", (UBYTE *)~0 );
          GT_BeginRefresh( APP_Window );
          DrawBitMap( HomeBM, OffX, OffY, (APP_Window->Width - (OffX + APP_Window->BorderRight)), (APP_Window->Height - (OffY + APP_Window->BorderBottom)), APP_Window->RPort );
          GT_EndRefresh( APP_Window, TRUE );
          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 );
}
