/****************************************************************************
 *
 *                                 WBDepth.c
 *
 * Programma per la modifica del numero di bitplanes del workbench.
 * Versione 0.9 del 10-Feb-1989.
 * Autore Eugenio Ciceri.
 * Posto in pubblico dominio tramite il numero 6 della rivista AMAZING.
 * Sono consentiti il libero uso, distribuzione e pubblicazione in qualunque
 * forma a patto che questo commento introduttivo rimanga inalterato.
 *
 ****************************************************************************/

#include "intuition/intuitionbase.h"
#include "exec/memory.h"
#include "functions.h"              /*** Solo per il compilatore AZTEC ******/

struct IntuitionBase *IntuitionBase=NULL;
struct GfxBase *GfxBase=NULL;
struct Screen *FirstScreen=NULL;
struct Window *w=NULL;
struct ColorMap *cm=NULL;
UWORD i,depth,actualdepth,width,height;
struct NewWindow nw =
{
    0,0,
    0,0,
    0,0,
    0,
    ACTIVATE,
    0,
    0,
    0,
    0,
    0,
    1,1,
    -1,-1,
    WBENCHSCREEN
};

UWORD *colortable;

/** I colori che verranno utilizzati dal WorkBench sono definiti qui ********/
UWORD colors[32] =
{
    0x0008,
    0x0ECA,
    0x0000,
    0x0C00,
    0x0F60,
    0x0FE0,
    0x000F,
    0x02CD,
    0x0090,
    0x03F1,
    0x0950,
    0x0B60,
    0x0CCC,
    0x0888,
    0x0666,
    0x0444,

    0x0008,
    0x0ECA,
    0x0000,
    0x0C00,
    0x0F60,
    0x0FE0,
    0x000F,
    0x02CD,
    0x0090,
    0x03F1,
    0x0950,
    0x0B60,
    0x0CCC,
    0x0888,
    0x0666,
    0x0444
};

/** ROUTINE PRINCIPALE ******************************************************/
main(argc,argv)
int argc;               /*** Contatore degli argomenti passati da CLI *******/
char *argv[];           /*** Matrice di puntatori agli argomenti ************/
{
/** Punta al primo argomento passato dopo il nome del programma *************/
    argv++;

/** Si aspetta che si tratti di un numero ***********************************/
    depth=atoi(*argv);

/** Se tale numero non c'e' o non e' compreso tra 1 e 4... ******************/
    if ((argc<=1)||(depth<1)||(depth>4))
    {
/****** ...spiega all'utente dove ha sbagliato ed esce **********************/
        printf("WBDepth by Eugenio Ciceri 1989.\n");
        printf("Syntax: WBDepth n_of_planes (1 to 4).\n");
        return NULL;
    }

/** Tenta di aprire la graphic library **************************************/
    if (!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0)))
    {
        printf("WBDepth: Non posso aprire la graphic library!\n");
        return FALSE;
    }

/** Tenta di aprire la intuition library ************************************/
    if (!(IntuitionBase=
        (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
    {
        printf("WBDepth: Non posso aprire la intuition library!\n");
        CloseLibrary(GfxBase);
        return FALSE;
    }

/** Tenta di raggiungere il puntatore allo schermo del workbench ************/
    if (!(FirstScreen=IntuitionBase->FirstScreen))
    {
        printf("WBDepth: IntuitionBase non ha FirstScreen.\n");
        CloseLibrary(IntuitionBase);
        CloseLibrary(GfxBase);
        return FALSE;
    }

/** Evita interferenze da altri tasks ***************************************/
    Forbid();

/** Preleva le dimensioni dello schermo di workbench ************************/
    width=FirstScreen->Width;
    height=FirstScreen->Height;
    actualdepth=FirstScreen->BitMap.Depth;

/** Azzera i puntatori ai bitplanes non usati *******************************/
    for (i=actualdepth; i<8; i++)
        FirstScreen->BitMap.Planes[i]=NULL;

/** Se e' stato richiesto un workbench piu'... leggero... *******************/
    if (depth<actualdepth)
    {
/****** ...libera la memoria occupata dai bitplanes in eccesso **************/
        for (i=actualdepth; i>depth; i--)
        {
            if(FirstScreen->BitMap.Planes[i-1])
                FreeRaster(FirstScreen->BitMap.Planes[i-1],
                           FirstScreen->BitMap.BytesPerRow*8,
                           FirstScreen->BitMap.Rows);
            FirstScreen->BitMap.Planes[i-1]=NULL;
        }
    }
/** Altrimenti **************************************************************/
    else
    {
/****** Tenta di aggiungere i bitplanes richiesti al workbench **************/
        for (i=actualdepth; i<depth; i++)
        {
            if (!(FirstScreen->BitMap.Planes[i]=
                (PLANEPTR)AllocMem((width+7)/8*height,MEMF_CHIP|MEMF_CLEAR)))
            {
                printf("WBDepth: Non c'e' memoria per i piani aggiuntivi\n");
                CleanUp();
                return FALSE;
            }
        }
    }

/** Modifica il dato profondita' nello schermo di workbench *****************/
    FirstScreen->BitMap.Depth=depth;

/** Disalloca la vecchia colormap del workbench... **************************/
    FreeColorMap(FirstScreen->ViewPort.ColorMap);
    FirstScreen->ViewPort.ColorMap=NULL;
/** ...e tenta di allocarne una per contenere i nuovi colori ****************/
    if (!(cm=(struct ColorMap *)GetColorMap(1<<depth)))
    {
        printf("WBDepth: Non c'e' memoria per ColorMap.\n");
        CleanUp();
        return FALSE;
    }
    FirstScreen->ViewPort.ColorMap=cm;

/** Copia i nuovi colori nella nuova colormap *******************************/
    colortable=(UWORD *)cm->ColorTable;
    printf("NUOVI COLORI:\n\n");
    for (i=0; i<cm->Count; i++)
    {
        *colortable=colors[i];
        printf("%2d=0x%03x\n",i,*colortable);
        colortable++;
    }

/** Ricostruisce il display utilizzando le modifiche apportate **************/
    RemakeDisplay();

/** Riabilita il multitasking ***********************************************/
    Permit();

/****************************************************************************
 *
 * Trucchettino carino per evitare di rinfrescare tutta la catena dei gadgets
 * presenti  nello  schermo  di  workbench:   si  apre  un finestrone a tutto
 * schermo e lo si richiude immediatamente obbligando in tal modo Intuition a
 * rinfrescare automaticamente il  tutto...  chissa'  se  funziona  sempre...
 *
 ****************************************************************************/
    nw.Width=FirstScreen->Width;
    nw.Height=FirstScreen->Height;
    nw.Screen=FirstScreen;
    if (w=OpenWindow(&nw))
        CloseWindow(w);
}

/** ROUTINE DI USCITA 'PULITA' **********************************************/
CleanUp()
{
/** Disabilita il multitasking **********************************************/
    Forbid();

/** Libera la memoria degli eventuali bitplanes in eccesso ******************/
    FirstScreen->BitMap.Depth=actualdepth;
    for (i=8; i>actualdepth; i--)
    {
        if(FirstScreen->BitMap.Planes[i-1])
            FreeRaster(FirstScreen->BitMap.Planes[i-1],
                       FirstScreen->BitMap.BytesPerRow*8,
                       FirstScreen->BitMap.Rows);
        FirstScreen->BitMap.Planes[i-1]=NULL;
    }

/** Riabilita il multitasking ***********************************************/
    Permit();

/** Richiude le librerie ****************************************************/
    if (IntuitionBase)
        CloseLibrary(IntuitionBase);
    if (GfxBase)
        CloseLibrary(GfxBase);
}
