/*************************************************************************
/*                                                                       *
/* C-Beispielprogramm für die Get-It ( Diskettenmagazin der AIT-UG )     *
/* geschrieben von Peter Fischer, RP.-Ebert-Str. 6, D-3257 Springe 1     *
/* Telefon : 05041/63563                                                 *
/*                                                                       *
/* Kurs 9 : Systemroutinen                                               *
/* Datum : 9.10.89                                                       *
/*                                                                       *
/* Copyrights (c)'89 by PeeF.                                            *
/* Der ausführbare Code ist Public Domain in bester Manier.              *
/* Der Quellcode darf von jedem/r GetiT-Leser/in benutzt werden, wie es  *
/* in seinem/ihrem Interesse liegt.                                      *
/*                                                                       *
/*************************************************************************/
/*                                                                       *
/* Dieser File muß mit dem File image.o gelinkt werden.                  *
/* Kompilieren mit                                                       *
/* cc +p c9_2                                                            *
/* Linken mit                                                            *
/* ln -cl32 -a32 c9_2 image                                              *
/*                                                                       *
/*************************************************************************/

/* Include-Files. */
#include <intuition/intuition.h>
#include <exec/exec.h>
#include <graphics/gfx.h>
#include <stdio.h>
#include <libraries/arpbase.h>

/* Für AmigaDOS & Co                                                     */
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct ArpBase *ArpBase = NULL;

/* Alle die Variablen für Intuition für Screens und Fenster.             */
struct NewScreen NewScr =
{ 0,0,640,256,4,11,2,HIRES,CUSTOMSCREEN,
  NULL,"Ein Screen für alle Fälle ! Folge -9-",NULL,NULL
};
struct Screen *Scr = NULL;

struct NewWindow 
  NeuFenster =
  { 0,10,640,246,0,1,
    CLOSEWINDOW | MENUPICK,
    WINDOWCLOSE | NOCAREREFRESH | ACTIVATE,
    NULL,NULL,NULL,
    NULL,NULL,300,10,640,256,CUSTOMSCREEN
  };

struct Window *Fenster = NULL;
struct RastPort *rp;
/* Für den Titel auf dem Screen. */

/* Festlegung der Farben.                                                */
int Farbe[16][3] =
{ {  0, 0, 0 },                            /* Schwarz                    */
  { 15,15,15 },{ 12,12,12 },{  8, 8, 8 },  /* WEISS bis grau             */
  {  8, 0, 0 },{ 12, 0, 0 },{ 15, 0, 0 },  /* Rot                        */
  {  0, 8, 0 },{  0,12, 0 },{  0,15, 0 },  /* Grün                       */
  {  0, 0, 8 },{  0, 0,12 },{  0, 0,15 },  /* Blau                       */
  {  8, 0, 8 },{ 12, 0,12 },{ 15, 0,15 },  /* Lila                       */
};

/*************************************************************************
 * MEIN AIT-Zeiger. Keine COPYRIGHTS, darf jeder benutzen !              */
UWORD ptr[] =
{ 0x00  ,0x00,
  0x0000,0x0100,  0x0000,0x0280,  0x0000,0x0440,  0x0000,0x0280,
  0x0000,0x0100,  0x0000,0x0000,  0x31BF,0x1081,  0x798C,0x2884,
  0x798C,0x2884,  0x798C,0x2884,  0x798C,0x2884,  0xFD8C,0x0484,
  0xCD8C,0x4484,  0xCD8C,0x4484,  0xCD8C,0x4484,  0x0000,0x0000,
  0x00  ,0x00
}, *cptr = NULL;

/*************************************************************************
/* Die Images und Texte für die Items.                                   */
struct IntuiText
  text[] = 
  { { 4,0,JAM1,0,0,NULL,"Aktiviere `Noch Nix'",NULL },
    { 4,0,JAM1,0,0,NULL,"Deaktiviere `Noch Nix'",NULL },
    { 5,0,JAM1,20,10,NULL,"Dieser C-Kurs wurde geschrieben von",&text[5] },
    { 4,0,JAM1,20,0,NULL,"Aber jetzt is was !",NULL },
    { 2,0,JAM1,0,0,NULL,"Genug !!!",NULL },
    { 6,0,JAM1,50,30,NULL,"Peter Fischer",&text[6] },
    { 6,0,JAM1,50,40,NULL,"RP.-Ebert-Str. 6",&text[7] },
    { 6,0,JAM1,50,50,NULL,"D-3257 Springe 1",&text[8] },
    { 6,0,JAM1,50,60,NULL,"BRDeutschland",&text[9] },
    { 5,0,JAM1,20,100,NULL,"für die",&text[10] },
    { 7,0,JAM1,100,150,NULL,"GetiT",NULL }
  };

/* Die Variablen und Deklarationen der Images werden alle im File */
/* image.c abgehandelt.                                           */
extern struct Image Image1, Image2, Image3, Image4, Image5, Image6;
extern USHORT *IChip1, *IChip2, *IChip3, *IChip4, *IChip5, *IChip6;
extern USHORT IData1[], IData2[], IData3[], IData4[], IData5[], IData6[];

/*************************************************************************
/* Daten für die Items.                                                  */
struct MenuItem
  item[] =
  { { &item[ 1], 0,  0, 85, 45,ITEMENABLED | HIGHIMAGE | COMMSEQ,
      NULL,&Image1,&Image2,'1',NULL,NULL 
    },
    { &item[ 2], 0, 50, 85, 45,ITEMENABLED | HIGHIMAGE | COMMSEQ,
      NULL,&Image3,&Image4,'2',NULL,NULL 
    },
    { NULL,      0,100, 85, 45,ITEMENABLED | HIGHIMAGE | COMMSEQ,
      NULL,&Image5,&Image6,'3',NULL,NULL 
    },
    { &item[ 4], 0,  0,200, 10,ITEMTEXT | ITEMENABLED | HIGHBOX,
      NULL,&text[0],NULL,NULL,NULL,NULL
    },
    { NULL,      0, 10,200, 10,ITEMTEXT | ITEMENABLED | HIGHBOX,
      NULL,&text[1],NULL,NULL,NULL,NULL
    },
    { NULL,   -100,  0,300,200,ITEMTEXT | ITEMENABLED | HIGHCOMP,
      NULL,&text[2],NULL,NULL,NULL,NULL
    },
    { NULL,    -30,  0,200, 20,ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT,
      NULL,&text[3],NULL,NULL,NULL,NULL
    },
    { NULL,      0,  0,100, 20,ITEMTEXT | ITEMENABLED | HIGHBOX,
      NULL,&text[4],NULL,NULL,NULL,NULL
    }
  };

/*************************************************************************
/* Daten für die Menüs.                                                  */
struct Menu menu[] =
{ { &menu[1],  0,0, 50,10,MENUENABLED,"Bilder",  &item[0] },
  { &menu[2], 60,0, 70,10,MENUENABLED,"Aktionen",&item[3] },
  { &menu[3],140,0, 45,10,MENUENABLED,"About",   &item[5] },
  { &menu[4],190,0, 30,10,MENUENABLED,"Nix",     NULL },
  { &menu[5],220,0, 70,10,MENUENABLED,"Noch nix",&item[6] },
  { NULL    ,300,0, 50,10,MENUENABLED,"Schluß",  &item[7] },
};

/*************************************************************************
/* Start des Hauptprogramms.                                             */
main()
{ struct IntuiMessage *msg;
  int i;
  static char fehler[] = "Kein Platz für Image.";
  ULONG class, DoMenue();
  USHORT code;
  /* An dieser Stelle steht ein Wert im System, der sich laufend ändert. */
  /* Allerdings ist dies nicht die feine englische Art, ihn auf diese    */
  /* Weise zu bestimmen. Es geht nur im Moment nicht einfacher.          */
  unsigned int *seed = (unsigned int *)0xdff006;

  /* Der Startwert für den Zufallszahlengenerator. */
  srand(*seed);

  /* Alle Initialisationen. ( Watn Wort )                                */
  init();

  /* Die Daten für die Images werden ins ChipMem transferiert. */
  IChip1 = CopyIDataToChip ( IData1,&Image1 );
  if ( IChip1 == NULL )
    notaus ( fehler );
  IChip2 = CopyIDataToChip ( IData2,&Image2 );
  if ( IChip2 == NULL )
    notaus ( fehler );
  IChip3 = CopyIDataToChip ( IData3,&Image3 );
  if ( IChip3 == NULL )
    notaus ( fehler );
  IChip4 = CopyIDataToChip ( IData4,&Image4 );
  if ( IChip4 == NULL )
    notaus ( fehler );
  IChip5 = CopyIDataToChip ( IData5,&Image5 );
  if ( IChip5 == NULL )
    notaus ( fehler );
  IChip6 = CopyIDataToChip ( IData6,&Image6 );
  if ( IChip6 == NULL )
    notaus ( fehler );

  /* Menu setzen.                                                      */
  SetMenuStrip ( Fenster,&menu[0] );
  /* Hinweis auf Menu.                                                 */
  SetWindowTitles ( Fenster,"MenüTest",-1 );
  /* MEINEN Mauszeiger setzen.                                         */
  SetPointer ( Fenster,cptr,16,16,-8,-3 );
  /* Schleife, mit der die Menüs abgefragt werden.                     */
  do
  { Wait ( 1 << Fenster->UserPort->mp_SigBit );
    msg = GetMsg ( Fenster->UserPort );
    class = msg->Class;
    code = msg->Code;
    class = DoMenue ( class,code );
    do
    { ReplyMsg ( msg );
      msg = GetMsg ( Fenster->UserPort );
    } while ( msg != NULL );
  } while ( class != CLOSEWINDOW );
  notaus( NULL );
}

/* Verarbeitung der Menüs. */
ULONG DoMenue( class,code )
ULONG class;
USHORT code;
{ BOOL error = FALSE;

  if ( class == CLOSEWINDOW )
    return ( CLOSEWINDOW );
  switch ( MENUNUM ( code ) )
  { case 0 :
      error = Bild(ITEMNUM(code));
      break;
    case 1 :
      error = action(ITEMNUM(code));
      break;
    case 2 :
      break;
    case 3 :
      break;
    case 4 :
      if ( ITEMNUM(code) == 0 )
        toggle();
      else
        error = TRUE;
      break;
    case 5 :
      if ( ITEMNUM(code) == 0 )
        return ( CLOSEWINDOW );
      else
        error = TRUE;
      break;
    default :
      error = TRUE;
      break;
  }
  if ( error )
    DisplayBeep ( Scr );
  return ( MENUPICK );
}

/* Die Bilder werden verarbeitet. */
Bild ( nr )
int nr;
{ int x,y;

  /* Zufallswerte für die Position werden geholt. Als Grenzwerte sind   */
  /* für den horizontalen Wert 0 bis 579 zugelassen, für den vertikalen */
  /* Wert Zahlen zwischen 10 und 190.                                   */
  x = rand() % 580;
  y = ( rand() % 180 ) + 10;
  /* Abhängig von der Wahl des Eintrags werden die Menüs gezeichnet.    */
  if ( nr == 0 )
    DrawImage(rp,&Image2,x,y );
  else if ( nr == 1 )
    DrawImage(rp,&Image4,x,y );
  else if ( nr == 2 )
    DrawImage(rp,&Image6,x,y );
  /* Falls ein Fehler auftritt, wird TRUE zurückgegeben. */
  else
    return ( TRUE );
  return( FALSE );
}

/* Das Aktionsmenü wird bearbeitet. */
action ( nr )
int nr;
{ if ( nr == 0 )
    OnMenu ( Fenster,4 );
  else if ( nr == 1 )
    OffMenu ( Fenster,4 );
  else 
    return ( TRUE );
  return ( FALSE );
}

/* Das Häkchen wird gesetzt oder zurückgesetzt. */
toggle()
{ static int check = FALSE;

  check = ~check;
  if ( ! check )
    item[6].Flags &= ~CHECKED;
}

/* Routine, die alles wieder aus dem Speicher entfernt ( bzw entfernen   *
/* soll) . Gibt im Fehlerfall eine Meldung auf den Bildschirm aus, auch  *
/* für WORKBENCHer wie Jochen und Magnus.                                */
notaus ( txt )
char *txt;
{ FILE *aus,*fopen();
  int i;

  /* Pointer wieder restaurieren. Eigentlich wohl überflüssig, oder ?    */
  ClearPointer ( Fenster );
  /* Alles wech !                                                        */
  if ( cptr != NULL )
    FreeMem( cptr,36 * sizeof(UWORD) );
  if ( Fenster != NULL )
    CloseWindow ( Fenster );
  FreeChipData ( &Image1,IData1 );
  FreeChipData ( &Image2,IData2 );
  FreeChipData ( &Image3,IData3 );
  FreeChipData ( &Image4,IData4 );
  FreeChipData ( &Image5,IData5 );
  FreeChipData ( &Image6,IData6 );
  if ( Scr != NULL )
    CloseScreen ( Scr );
  if ( ArpBase != NULL )
    CloseLibrary ( ArpBase );
  /* Ausgabe der Fehlermeldung.                                          */
  if ( txt != NULL )
  { aus = fopen ( "CON:0/108/320/80/ABBRUCH","w" );
    fprintf ( aus,"%s\n",txt );
    fprintf ( aus,"Das Programm wird abgebrochen !\n" );
    Delay ( 150L );
    fclose ( aus );
    exit(100);
  }
  exit ( 0 );
}

/* Initialisierungen                                                     */
init()
{ int i;

  ArpBase = OpenLibrary ( "arp.library",0 );
  if ( ArpBase == NULL )
    notaus ( "arp.library läßt sich nicht öffnen !" );

  IntuitionBase = ArpBase->IntuiBase;
  GfxBase = ArpBase->GfxBase;

  Scr = OpenScreen ( &NewScr );
  if ( Scr == NULL )
    notaus ( "Screen läßt sich nicht öffnen !" );

  for ( i = 0; i < 16; i++ )
    SetRGB4 ( &(Scr->ViewPort),i,Farbe[i][0],Farbe[i][1],Farbe[i][2] );

  NeuFenster.Screen = Scr;
  Fenster = OpenWindow( &NeuFenster );
  if ( Fenster == NULL )
    notaus ( "Fenster läßt sich nicht öffnen !" );
  rp = Fenster->RPort;

  cptr = AllocMem ( 36 * sizeof(UWORD),MEMF_CHIP );
  if ( cptr == NULL )
    notaus( "Zu wenig Speicher für den Pointer !" );
  for ( i = 0; i < 36; i++ )
    cptr[i] = ptr[i];
}
