/* Layers.c */

#include <exec/types.h>
#include <graphics/gfxbase.h>
#include <graphics/layers.h>
#include <graphics/clip.h>
#include <intuition/intuition.h>

#ifdef LATTICE
# include <proto/dos.h>
# include <proto/layers.h>
# include <proto/graphics.h>
# include <proto/exec.h>
#else
# include <functions.h>
#endif

#define DEPTH 2  
#define WIDTH 320 
#define HEIGHT 200 
#define NOT_ENOUGH_MEMORY -1000 

#define FLAGS LAYERSMART
struct View       *oldview, v;
struct ViewPort   vp;
struct ColorMap   *cm;    /* Puntatore a ColorMap */
struct RasInfo    ri;
struct BitMap     b;
struct GfxBase    *GfxBase;
struct LayersBase *LayersBase;
struct LayerInfo  *li;
struct Layer *layer[ 3 ];
struct RastPort   *rp[3]; /* Rastport per ciascun Layer */

SHORT i, j, k, n;
SHORT  boxoffsets[] = { 802, 2010, 3218 };
USHORT colortable[] = { 0x000, 0xf00, 0x0f0, 0x00f };
                        /* nero, rosso, verde, blu */
UBYTE *displaymem, *colorpalette;

/* Routine di pulizia per uscita corretta */

void FreeMemory()
{
 for( i = 0 ; i < DEPTH; i++ ) /* Libera area di tracciatura */
   FreeRaster( b.Planes[i], WIDTH, HEIGHT );
 FreeColorMap( cm ); /* Libera la colormap */

/* Libera strutture create dinamicamente */
 FreeVPortCopLists( &vp ); FreeCprList( v.LOFCprList );
} 

void _main()
{
 GfxBase = (struct GfxBase *)\
   OpenLibrary( "graphics.library", 0 );
 if ( GfxBase == NULL ) _exit( 1L );

 LayersBase = (struct LayersBase *)\
   OpenLibrary( "layers.library", 0 );
 if( LayersBase == NULL ) _exit( 2L );

 /* Leggiamo View, se da Workbench, leggiamo da Intuition */
 oldview = GfxBase -> ActiView;
 
 /* Legge struttura LayerInfo */
 li = NewLayerInfo(); /* Legge struttura LayerInfo */
 if ( li == NULL ) _exit( 100L );

 /* Inizializza View */ 
 InitView( &v );
 /* Fonde View in ViewPort */
 v.ViewPort = &vp;

 /* Inizializza viewport /*
 InitVPort( &vp );

 /* Ora specifica caratteristiche critiche */
 
 vp.DWidth = WIDTH;   /* Larghezza */
 vp.DHeight = HEIGHT; /* Altezza */
 vp.RasInfo = &ri;    /* RasInfo, raster temporaneo */

 /* Inizializza Bitmap (per rasinfo e rastport) */
 InitBitMap( &b, DEPTH, WIDTH, HEIGHT );
 
 /* (Inizializza RasInfo) */
 ri.BitMap = &b;
 ri.RxOffset = 0;

 /* Allinea spigolo superiore sinistro con bordo superiore */
 ri.RyOffset = 0;
 ri.Next = NULL;

 /* (inizializza tabella colori) */

 cm = GetColorMap( 4 ); /* 4 elementi, 2 soli bitplanes */
 colorpalette = (UBYTE *) cm -> ColorTable;
 for( i = 0 ; i < 4 ; i++ ) /* Copia colori */
   *colorpalette++ = colortable[ i ];

 /* Ricopia colori in struttura dati */
 
 vp.ColorMap = cm; /* Aggancia a viewport */

 /* Alloca spazio per la bitmap */
 
 for( i = 0 ; i < DEPTH ; i++ )
   {
   b.Planes[i] = (PLANEPTR) AllocRaster( WIDTH, HEIGHT );
   if ( b.Planes[i] == NULL )
     _exit( NOT_ENOUGH_MEMORY );
   }
 MakeVPort( &v, &vp ); 
 MrgCop( &v ); 

 for( i = 0; i < 2; i++ ) /* Azzera i bytees di area */
   {
   displaymem = (UBYTE *) b.Planes[i];
   for( j = 0; j < RASSIZE( WIDTH,HEIGHT ); j++ )
     *displaymem++ = 0;
   }
   LoadView( &v );

   /* Riempiamo i box per visualizzarli */

 layer[0] = CreateUpfrontLayer( li, &b, 5,5,85,65, FLAGS, NULL );

 /* LayerInfo, bitmap comune, x,y,x2,y2, flags=0
    (simple-refresh), puntatore nullo a superbitmap */
 
 if( layer[0] == NULL ) goto cleanup1;
 
 layer[1] = CreateUpfrontLayer(li,&b,20,20,100,80,FLAGS,NULL);
 if( layer[1] == NULL ) goto cleanup2;

 layer[2] = CreateUpfrontLayer(li,&b,45,45,125,105,FLAGS,NULL);
 if ( layer[2] == NULL ) goto cleanup3;

 for( i = 0; i<3; i++) /* Layers creati, ora li tracciamo */
   {
   rp[ i ] = layer[ i ] -> rp;
   SetAPen( rp[ i ], i + 1 );
   SetDrMd( rp[ i ], JAM1 );
   RectFill( rp[ i ], 0, 0, 79, 59 );
   }

 /* Mettiamo un poco di testo nei Layers */
 SetAPen( rp[ 0 ], 0 ); Move( rp[ 0 ], 5, 30 );
 Text( rp[ 0 ],"Layer 0",7 );
 SetAPen( rp[ 1 ], 0 ); Move( rp[ 1 ], 5, 30 );
 Text( rp[ 1 ],"Layer 1",7 );
 SetAPen( rp[ 2 ], 0 ); Move( rp[ 2 ], 5, 30 );
 Text( rp[2], "Layer 2", 7 );
 Delay( 50L * 2 ); /* Attendiamo due secondi */
 BehindLayer( li, layer[2] ); /* Commuta Layers 2,3 */
 Delay( 50L * 2 ); /* Altro cambiamento dopo 2 sec. */
 UpfrontLayer( li, layer[0] ); /* Commuta Layers 1,2 */
 Delay( 50L * 2 ); /* Attendiamo 2 sec. prima di muovere */

 for( i=0 ; i < 30 ; i++ ) /* Sposta il layer centrale */
   {
   MoveLayer( li, layer[ 1 ], 1, 3 );
   }

cleanup3:
 LoadView( oldview );  /* Rimette View precedente */
 DeleteLayer( li, layer[ 2 ] );
cleanup2:
 DeleteLayer( li, layer[ 1 ] );
cleanup1:
 DeleteLayer( li, layer[ 0 ] );
 DisposeLayerInfo( li );
 FreeMemory();
 CloseLibrary( (struct Library *) LayersBase ); 
 CloseLibrary( (struct Library *) GfxBase );
}
