//************************************
//
// Name : GrList.c
//
//************************************


//**** Header files

//** OS Include files
#include <exec/memory.h>
#include <exec/lists.h>
#include <graphics/scale.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>

#include <datatypes/datatypes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>


//** OS function prototypes
#include <clib/alib_protos.h>
//#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <clib/datatypes_protos.h>
//#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>


//** OS function inline calls
//#include <pragmas/intuition_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/datatypes_pragmas.h>
//#include <pragmas/dos_pragmas.h>
#include <pragmas/graphics_pragmas.h>


//** ANSI C includes
#include <string.h>

//** Application include

#include "librarian.h"
#include "GrList.h"
#include "TDEBUG.h"


//**** Local Storage

static struct List GrList;


//**** Private functions


//**** Aux functions

void InitGrList(void) {
  NewList(&GrList);
} // InitGrList


void FlushNodesGr(void) {
  while (GrList.lh_Head->ln_Succ)
    FreeNodeGr( (struct GrNode *)(GrList.lh_Head) );
  return;
} // FlushNodesGr


//**** Aux functions2

struct GrNode *NewNodeGr(STRPTR name) {
  struct GrNode *grn;
  Object *obj;
  struct BitMapHeader *bmh;
  struct BitMap *bmap;
  BOOL aok=FALSE;

  if (NULL==DataTypesBase) return NULL;

  if (grn=(struct GrNode *)FindName(&GrList,name)) {
    grn->UseCount++;
    aok=TRUE;
  } else {
    grn=(struct GrNode *)AllocVec(sizeof(struct GrNode),MEMF_CLEAR|MEMF_PUBLIC|MEMF_REVERSE);
    if (grn) {
      grn->Node.ln_Name=AllocVec(strlen(name)+1,MEMF_REVERSE);
      if (grn->Node.ln_Name) strcpy(grn->Node.ln_Name,name);
      obj = NewDTObject(name, DTA_SourceType, DTST_FILE,
	DTA_GroupID, GID_PICTURE, PDTA_Remap, FALSE, TAG_DONE);
      if (obj) {
	if (1==GetDTAttrs(obj, PDTA_BitMapHeader, &bmh, TAG_DONE) ) {
	  if (DoDTMethod(obj,NULL,NULL,DTM_PROCLAYOUT,NULL,1)) {
	    if (1==GetDTAttrs(obj, PDTA_BitMap, &bmap, TAG_DONE) )  {
	      grn->Width=bmh->bmh_Width/2;
	      grn->Height=bmh->bmh_Height;
	      if (grn->bmap = AllocBitMap(bmh->bmh_Width, bmh->bmh_Height, bmh->bmh_Depth, 0, NULL)) {
		BltBitMap(bmap, 0,0, grn->bmap, 0,0, bmh->bmh_Width, bmh->bmh_Height, 0xC0, 0xFF, NULL);
		WaitBlit();
		grn->UseCount=1;
		AddTail(&GrList,(struct Node *)grn);
		aok=TRUE;
	      } else {
		DPRINT("GrList: NewNodeGr: AllocBitBap() Failed\n",0);
	      } // if allocBitMap
	    } else {
	      DPRINT("GrList: NewNodeGr: GetDTAttr()-2 Failed\n",0);
	    } // if GetDTAttrs-2
	  } else {
	    DPRINT("GrList: NewNodeGr: DoDTMethod()-1 Failed\n",0);
	  } // if DoDTMethod
	} else {
	  DPRINT("GrList: NewNodeGr: GetDTAttr()-1 Failed\n",0);
	} // if GetDTAttrs-1
	DisposeDTObject(obj);
      } else {
	DPRINT("GrList: NewNodeGr: Cannot get data type\n",0);
      } // if NewDT
    } else {
      DPRINT("GrList: NewNodeGr: Cannot alloc memory\n",0);
    }
  } // if already in list


  if (FALSE==aok) {
    if (grn) {
      if (grn->bmap) FreeBitMap(grn->bmap);
      if (grn->Node.ln_Name) FreeVec(grn->Node.ln_Name);
      FreeVec(grn);
    }
    return NULL;
  } else {
    return grn;
  }
} // NewNodeGr


void FreeNodeGr(struct GrNode *grn) {
  if (grn) {
    grn->UseCount--;
    if (0==grn->UseCount) {
      Remove((struct Node *)grn);
      if (grn->bmap) {
	WaitBlit();
	FreeBitMap(grn->bmap);
      } // if
      if (grn->Node.ln_Name) FreeVec(grn->Node.ln_Name);
      FreeVec(grn);
    } // if still in use
  } else {
    DPRINT("GrList: FreeNodeGr: NULL POINTER\n",0);
  }
  return;
} // FreeNodeGr

//**** End of file

