/*
\\		Support functions for MUIConstruct
*/

	#include <Global/Main_Global.h>
	#include <Default.img>

        
ULONG __chip ImageColours[]=
{
        0x00000000,0x00000000,0x00000000,0x31313131,0x63636363,0xa5a5a5a5,
        0x73737373,0x73737373,0x73737373,0xa5a5a5a5,0x94949494,0x73737373,
        0x94949494,0x94949494,0x94949494,0xa5a5a5a5,0xa5a5a5a5,0xa5a5a5a5,
        0xf7f7f7f7,0xa5a5a5a5,0x94949494,0xf7f7f7f7,0xf7f7f7f7,0xf7f7f7f7,
};


	Object *Lister;
	
	
struct Transfer * ASM SAVEDS Main_Construct( REG(a1) struct Module * ,
                                             REG(a2) APTR );
                                             
void ASM SAVEDS Main_Destruct( REG(a1) struct Transfer *,
                               REG(a2) APTR );
                               
void ASM SAVEDS Main_Display( REG(a1) struct Transfer *,
                                    REG(a2) char **);
                                    
                               
Init_Main_Lister( void )
{      
  
  KPrintF("Main_Lister.c : Init_Main_Lister()\n");      
  Global->Main_Lister = ListviewObject,
	                  MUIA_Listview_DoubleClick,TRUE,                     
	                  MUIA_Frame,MUIV_Frame_InputList,
	                  MUIA_Listview_List,NewObject(Global->HierarchyClass->mcc_Class,NULL,TAG_DONE),
	                  MUIA_Listview_ScrollerPos,MUIV_Listview_ScrollerPos_Right,
  	                End;	                  
 			                          
 DoMethod(App->Constructor_Group,MUIM_Group_InitChange);
 DoMethod(App->Constructor_Group,OM_ADDMEMBER,Global->Main_Lister);
 DoMethod(App->App,OM_ADDMEMBER,Global->ImageWindow = NewObject(Global->NewObjectClass->mcc_Class,NULL,TAG_DONE));
 DoMethod(App->Constructor_Group,MUIM_Group_ExitChange);
 
 //set(Global->ImageWindow,MUIA_Window_Open,TRUE);
}

/***********************************Hierarchy_Class******************************************\
\											     /
/  This Class Is Used To Select The Objects That Are To Be Used.                             \
\  and is a SUB_CLASS of the WINDOW Class.						     /
/  and uses the IMAGELIST Class.                                                             \
\********************************************************************************************/

ULONG ASM SAVEDS _Hierarchy_Dispatcher( REG(a0) struct IClass *cl,
					REG(a2) Object *o,
					REG(a1) Msg msg)
{
         KPrintF("Main_Lister.c : _Hierarchy_Dispatcher()\n");      
	switch(msg->MethodID)
	{
		case OM_NEW:         return(Hierarchy_New(cl,o,(APTR)msg));	
		case MUIM_DragQuery: return(Hierarchy_DragQuery(cl,o,(APTR)msg));
		case MUIM_DragDrop:  return(Hierarchy_DragDrop(cl,o,(APTR)msg));
		
		default:	     return(DoSuperMethodA(cl,o,(APTR) msg));
	}
}

ULONG Hierarchy_New(struct IClass *cl, Object *obj, struct opSet *msg)
{
  static const struct Hook Main_ConstructHook = { { NULL,NULL },(VOID *)Main_Construct  ,NULL,NULL };
  static const struct Hook Main_DisplayHook   = { { NULL,NULL },(VOID *)Main_Display    ,NULL,NULL };
  static const struct Hook Main_DestructHook  = { { NULL,NULL },(VOID *)Main_Destruct   ,NULL,NULL };	
	
         KPrintF("Main_Lister.c : _New()\n");      
        
        if(obj = (Object *)DoSuperNew(cl,obj,	                               
	                                      MUIA_List_DragSortable,FALSE,
  	                                      MUIA_List_Format,",,",
  	                                      MUIA_List_ConstructHook,&Main_ConstructHook,
			                      MUIA_List_DestructHook,&Main_DestructHook,                                                            
 			                      MUIA_List_DisplayHook,&Main_DisplayHook, 			                   
	                                 TAG_MORE,msg->ops_AttrList))
	    {
	    return((ULONG)obj);
	    }
  return(0);
}

ULONG Hierarchy_DragQuery( struct IClass *cl, Object *o, struct MUIP_DragQuery *msg)
{
 if(msg->obj==o)
   return(MUIV_DragQuery_Refuse);
   
 return(MUIV_DragQuery_Accept);
}

ULONG Hierarchy_DragDrop( struct IClass *cl,Object *o,struct MUIP_DragDrop *msg)
{
  struct Class *New_Class;
  struct Transfer *Other;
  struct Module   *Parent;
  LONG *Position_Pointer;
  LONG Position;
  KPrintF("Main_Lister.c : Hierarchy_DragDrop()\n");
  get(o,MUIA_List_DropMark,&Position_Pointer);
  Position = Position_Pointer;
  DoMethod(o,MUIM_List_GetEntry,Position-1,&Other);
  if(Other)
   {
    Parent = FindObjectName(Other->Normal);
   }
   else
   Parent=NULL;
  
  DoMethod(msg->obj,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&New_Class);
  if(New_Class)
  {
    
    if(Parent)
       Add_Object(New_Class->ClassName,Parent);
      else
       Add_Object(New_Class->ClassName,NULL);
      
  }
  else
  Display("Failed To Find An Active Class!");
  
  return(TRUE);
}

struct Transfer * ASM SAVEDS Main_Construct( REG(a1) struct Module *New_Module ,
                                             REG(a2) APTR MemoryPool)
{
 struct Transfer *Outgoing;
 int Depth = 0;
 
 int Index = 0;
 KPrintF("Main_Lister.c : Main_Construct()\n");
 Outgoing          = AllocPooled(MemoryPool,sizeof(struct Transfer));
 Outgoing->Altered = AllocPooled(MemoryPool,(strlen(New_Module->Name)+64));
 Outgoing->Normal  = AllocPooled(MemoryPool,strlen(New_Module->Name));
 Outgoing->Depth   = New_Module->TreeDepth;
 Depth             = New_Module->TreeDepth;
 
 while(Depth!=0)
 {
 Outgoing->Altered[Index]=32;
 Depth--;
 Index++;
 }
 
 strcat(Outgoing->Altered,New_Module->Name);
 strcpy(Outgoing->Normal,New_Module->Name);
 
 return(Outgoing);
}

void ASM SAVEDS Main_Destruct( REG(a1) struct Transfer *InComing,
                               REG(a2) APTR MemoryPool)
{
   KPrintF("Main_Lister.c : Main_Destruct()\n");
   FreePooled(MemoryPool,InComing->Normal,strlen(InComing->Normal));
   FreePooled(MemoryPool,InComing->Altered,(strlen(InComing->Normal)+64));
   FreePooled(MemoryPool,InComing,sizeof(struct Transfer));
}

void ASM SAVEDS Main_Display( REG(a1) struct Transfer *Pending,
                                    REG(a2) char **Array)
{ 
	KPrintF("Main_Lister.c : Main_Display()\n");
	*Array++   = "\33I[6:MUII_TapeDown]";
	*Array     = Pending->Altered;
	return(0);
}



/***********************************NewObject_Class******************************************\
\											     /
/  This Class Is Used To Select The Objects That Are To Be Used.                             \
\  and is a SUB_CLASS of the WINDOW Class.						     /
/  and uses the IMAGELIST Class.                                                             \
\********************************************************************************************/

ULONG ASM SAVEDS _NewObject_Dispatcher( REG(a0) struct IClass *cl,
					REG(a2) Object *o,
					REG(a1) Msg msg)
{
        KPrintF("Main_Lister.c : _NewOBJect_Dispatcher()\n");
	switch(msg->MethodID)
	{
		case OM_NEW:     return(NewObject_NEW(cl,o,(APTR)msg));		
		default:	 return(DoSuperMethodA(cl,o,(APTR) msg));
	}
}

ULONG NewObject_NEW(struct IClass *cl, Object *obj, struct opSet *msg)

{
	struct Object   *ListView;
	struct Class	*New_Class;
        
	
	KPrintF("Main_Lister.c : NewObject_NEW()\n");
        if(obj = (Object *)DoSuperNew(cl,obj,
	                              WindowContents,VGroup,
	                               Child, Lister = ListviewObject,
	                                  MUIA_Listview_DoubleClick,TRUE,
	                                  MUIA_Frame,MUIV_Frame_InputList,
	                                  
	                                  MUIA_Listview_DragType,MUIV_Listview_DragType_Immediate,                                  
	                                  MUIA_Listview_List,ListView = NewObject(Global->ImgListClass->mcc_Class,NULL,TAG_DONE),
	                               End,
	                              End,
	                             TAG_MORE,msg->ops_AttrList))
	    {
	     
	     for(New_Class = Global->ClassList.mlh_Head;
                 New_Class->mln_Succ;
                 New_Class = New_Class->mln_Succ)
                  {              
	           DoMethod(Lister,MUIM_List_InsertSingle,New_Class,MUIV_List_Insert_Bottom); 
	          }
	     
	     set(obj,MUIA_Window_Title,"Object_Selector");
	     set(obj,MUIA_Window_ID , MAKE_ID('S','L','C','T'));
	              
	     
             return((ULONG)obj);
            }
            
            else
            {
             Display("NewObject Class Failed To Happen!");
            return(0);
            }
}



/***********************************ImageList Class*******************************************\
\											      /
/   This Class Is Used In The List View Of The Object_Selector Class			      \
\   and is a SUB_CLASS of the LIST Class.                                                     /
/                                                                                             \
\*********************************************************************************************/

ULONG ASM SAVEDS _ImageList_Dispatcher( REG(a0) struct IClass *cl,
                                        REG(a2) Object *o,
                                        REG(a1) Msg    msg )
{
     KPrintF("Main_Lister.c : _ImageList_Disptacher()\n");
     switch(msg->MethodID)
     {
         case OM_NEW:       return(ImageList_New(cl,o,(APTR) msg));
         case MUIM_Setup:   return(ImageList_Setup(cl,o,(APTR) msg));
         case MUIM_Cleanup: return(ImageList_Cleanup(cl,o,(APTR) msg));
         default:           return(DoSuperMethodA(cl,o,(APTR) msg));
     }
}

ULONG ImageList_New(struct IClass *cl, Object *obj, struct opSet *msg)
{       
        extern void           ASM SAVEDS Image_Display(     REG(a1) struct Class * ,REG(a2) char **);               
        static const struct Hook ImageList_DisplayHook = { { 0,0 }, (VOID *)Image_Display,NULL,NULL};
        KPrintF("Main_Lister.c : ImageList_New()\n");
  obj = (Object *)DoSuperNew(cl, obj,           
                     MUIA_List_DisplayHook   , &ImageList_DisplayHook,
                     MUIA_List_Format        , "DELTA=2,",
                     MUIA_List_MinLineHeight , 40,
                     MUIA_List_AdjustHeight,TRUE,
	             MUIA_List_AdjustWidth,TRUE,
                     TAG_MORE, msg->ops_AttrList);
  
    
  return((ULONG)obj);
   
}

ULONG ImageList_Setup( struct IClass *cl, Object *o, struct MUIP_Setup *msg)
{
  struct EMC_Data *Xfer;
  struct Class    *New_Class;
  char            *Handy_Buffer;
  
  ASM ULONG (*Launch_Pad)( REG(d0) struct EMC_Data * ); 
         KPrintF("Main_Lister.c : ImageList_Setup()\n");
         Xfer 		= AllocPooled(Global->MemoryPool,sizeof(struct EMC_Data));
         Handy_Buffer	= AllocPooled(Global->MemoryPool,255);    
         
       for(New_Class = Global->ClassList.mlh_Head;
             New_Class->mln_Succ;
             New_Class = New_Class->mln_Succ)
             {  
             if(!New_Class->SegList)
             {
                sprintf( Handy_Buffer, "PROGDIR:ClassModules/%s.ext", New_Class->ClassName );
                New_Class->SegList = LoadSeg( Handy_Buffer );
                if(!New_Class->SegList) 
                     Display("MAJOR Problem.\nFailed To LoadSeg() Current Class!");
                     
                New_Class->Launcher = (((ULONG)New_Class->SegList)<<2) + 4;// Code starts seglist + 4;
                Init_EMC_Data( New_Class->ClassName,Xfer,FALSE,FALSE,FALSE);
                Xfer->Command = EXTMOD_INIT;
                Launch_Pad = New_Class->Launcher;
                New_Class->Flags = Launch_Pad( Xfer );
                if(Xfer->Image_Object)
                New_Class->Image_Object = DoMethod(o,MUIM_List_CreateImage,Xfer->Image_Object);                                                           
                else
                New_Class->Image_Object = DoMethod(o,MUIM_List_CreateImage,StandardImage());
                if(New_Class->SegList)
                   {
                    UnLoadSeg(New_Class->SegList);
                    New_Class->SegList=NULL;
                   }
             }
             else
             {
               Init_EMC_Data(New_Class->ClassName,Xfer,FALSE,FALSE,FALSE);
               Xfer->Command = EXTMOD_INIT;
               Launch_Pad = New_Class->Launcher;
               New_Class->Flags = Launch_Pad( Xfer);
               if(Xfer->Image_Object)
               New_Class->Image_Object = DoMethod(o,MUIM_List_CreateImage,Xfer->Image_Object);
               else
               New_Class->Image_Object = DoMethod(o,MUIM_List_CreateImage,StandardImage());
             }
             
            }
            FreePooled(Global->MemoryPool,Xfer,sizeof(struct EMC_Data));  
            FreePooled(Global->MemoryPool,Handy_Buffer,255);
            
  return(DoSuperMethodA(cl,o,msg));
}



ULONG ImageList_Cleanup( struct IClass *cl, Object *o, APTR msg)
{
 struct Class *New_Class;
 KPrintF("Main_Lister.c : ImageList_Cleanup()\n");
 for(New_Class = Global->ClassList.mlh_Head;
             New_Class->mln_Succ;
             New_Class = New_Class->mln_Succ)
             {
             
             if(New_Class->Image_Object)
                 DoMethod(o,MUIM_List_DeleteImage,New_Class->Image_Object);
             }
             
 return((ULONG )DoSuperMethodA(cl,o,msg));
}
    
                          
void ASM SAVEDS Image_Display( REG(a1) struct Class *New_Data,
                               REG(a2) char **Array)

{
    char *ImageBuffer;
    ImageBuffer = AllocPooled(Global->MemoryPool,30);
    
    sprintf(ImageBuffer,"\33O[%08lx]",New_Data->Image_Object);
    
    *Array++ =  ImageBuffer;
    *Array   =  New_Data->ClassName;
   
}


Object * StandardImage( void )
{
  Object *Image_Object;
   Image_Object = BodychunkObject,ImageButtonFrame, 			
                      MUIA_Bodychunk_Body	, &Body_Data,
                      MUIA_Bodychunk_Compression, BODY_COMPRESSION,
                      MUIA_Bodychunk_Depth	, BODY_DEPTH,
                      MUIA_Bitmap_Width		, BODY_WIDTH,
                      MUIA_Bitmap_Height	, BODY_HEIGHT,
                      MUIA_FixWidth             , BODY_WIDTH,
                      MUIA_FixHeight            , BODY_HEIGHT,         
                      MUIA_Bitmap_SourceColors	,&Body_Colour,
                      MUIA_Bitmap_Precision	, PRECISION_EXACT,                                          
                   End; 
 return(Image_Object);

}
