/* ******************************************************************** */
/* C code generated by:							*/
/* Visual Arts Version 1.0						*/
/* Copyright 1994 Danny Y. Wong  All rights reserved			*/
/* Calgary, Alberta (CANADA)                        			*/
/* Partial of the code is copyright by Jaba Development			*/
/* ******************************************************************** */

/*  this program demostrates the MultiProcessing windows.  The source
    was generated with the ALL option set.  I also added two additional
    lines in order to link to the sub program.
    
    extern void MultiSub(void);  //our sub program
    
    MultiSub();  //at the main which called to open the window


    Note: when you select the CLOSEGADGET codes are executed to close
    down the multiprocessing windows.  If you exist the event handling
    loop with a return, the window will lock up and will not be closed.
    If you have a button for existing, you should duplicate the codes
    in the IDCMP_CLOSEWINDOW and place it where you would exit the loop.
    This will ensure that the window with be closed.  You could make this
    a function for existing where you can easily be called.  This will be
    fixed for registed users.
*/    


#include <exec/types.h>
#include <exec/memory.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <libraries/gadtools.h>
#include <libraries/dos.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/asl_protos.h>
#include "string.h" 
#include "stdlib.h" 

#define ID_models                         			0

#define ModelsNumGads			1
#include "MultiMain.h" 

extern void MultiSub(void);     //extern program

int modelsObj(struct VAobject VAObject);

int GetPubScreen(void);
void ClosePubScreen(void);
int OpenModelsWindow(char windtitle[80]);
void CloseModelsWindow(void);
int ModelsHandler(void);
int ModelsMainHandler(void);
void DrawModelsObjs(void);
int main(int argc, char *argv[]);

UBYTE				*PubScrName = NULL;
APTR				 VisualInfo = NULL;
struct Screen			*Scr = NULL;
struct WindowNode		*ModelsActiveWind = NULL;
struct Gadget			*ModelsGList = NULL;
struct Gadget			*ModelsGadgets[1];
struct IntuiMessage		 ModelsMsg;
UWORD				 ModelsLeft = 30;
UWORD				 ModelsTop = 29;
UWORD				 ModelsWidth = 186;
UWORD				 ModelsHeight = 93;
struct IntuitionBase		*IntuitionBase = NULL;
struct List			*ModelsWindList;
UWORD				 ModelsTotalWindows = 0;
UWORD				 ModelsNumWindows = 0;
struct TextAttr topaz800 = { (STRPTR)"topaz.font", 8, 0x00, 0x00 };
struct TextAttr topaz8465 = { (STRPTR)"topaz.font", 8, 4, 65 };

UBYTE *ModelsLabels[] = {
	(UBYTE *)"Amiga 500", 
	(UBYTE *)"Amiga 600", 
	(UBYTE *)"Amiga 1000", 
	(UBYTE *)"Amiga 1200", 
	(UBYTE *)"Amiga 2000", 
	(UBYTE *)"Amiga 2500", 
	(UBYTE *)"Amiga 2500HD", 
	(UBYTE *)"Amiga 3000", 
	(UBYTE *)"Amiga Unix", 
	(UBYTE *)"Amiga 4000", 
	(UBYTE *)"Amiga 4000T", 
	(UBYTE *)"Amiga CDTV", 
	(UBYTE *)"Amiga CD32", 
	NULL
};

WORD ModelsGadTypes[] = {
	LISTVIEW_KIND,
};

struct NewGadget ModelsNGads[] = {
	6, 2, 163, 76, (UBYTE *)"", &topaz8465, ID_models, PLACETEXT_ABOVE, NULL, (APTR)modelsObj,
};

ULONG ModelsNTags[] = {
	(GTLV_Labels), NULL, (GTLV_Top), 0, (GTLV_ScrollWidth), 16, (LAYOUTA_Spacing), 0, TAG_DONE,
};


int GetPubScreen(void)
{
  if (!(Scr = LockPubScreen(PubScrName)))
	return(1L);

  if (!(VisualInfo = GetVisualInfo(Scr, TAG_DONE)))
	return(2L);
  return(0L);
}

void ClosePubScreen(void)
{
  if (VisualInfo)
    FreeVisualInfo(VisualInfo);
  if (Scr)
    UnlockPubScreen(NULL,  Scr);
}

int OpenModelsWindow(char windtitle[80])
{
  struct NewGadget	NewGad;
  struct Gadget   	*Gad;
  register UWORD i, j;
  UWORD offsetx = Scr->WBorLeft;
  UWORD offsety = Scr->WBorTop + Scr->RastPort.TxHeight + 1;

 if (ModelsNumWindows == 0)
 {
  if (!(Gad = CreateContext(&ModelsGList)))
  	return(1L);

  for (i=0, j=0; i < ModelsNumGads; i++)
  {
    CopyMem((char *)&ModelsNGads[i], (char *)&NewGad, (long)sizeof(struct NewGadget));

    NewGad.ng_VisualInfo = VisualInfo;
    NewGad.ng_LeftEdge += offsetx;
    NewGad.ng_TopEdge  += offsety;

    ModelsGadgets[i] = Gad = CreateGadgetA((ULONG)ModelsGadTypes[i], Gad,&NewGad,
	(struct TagItem *)&ModelsNTags[j]);
    while (ModelsNTags[j])
        j +=2;
    j++;
    if (!Gad)
       return(2L);
  }
 }
  if (!(ModelsActiveWind = AddWindowNode(ModelsWindList, windtitle, ModelsHandler)))
     return(1);
  if (!(ModelsActiveWind->nn_Window = OpenWindowTags(NULL,
  	WA_Left,	ModelsLeft,
  	WA_Top, 	ModelsTop,
  	WA_Width,	ModelsWidth,
  	WA_Height,	ModelsHeight - Scr->WBorTop,
  	WA_IDCMP,	IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_VANILLAKEY | IDCMP_INTUITICKS | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW ,
  	WA_Flags,	WFLG_CLOSEGADGET  |  WFLG_SMART_REFRESH |  WFLG_RMBTRAP |  WFLG_ACTIVATE |  WFLG_DRAGBAR ,
  	WA_Gadgets,	ModelsGList,
  	WA_Title,	windtitle,
  	WA_ScreenTitle,	"Visual Arts V1.0 Copyright 1994 Danny Y. Wong  All Rights Reserved.",
  	WA_PubScreen,	Scr,
  	WA_MinWidth,	20,
  	WA_MinHeight,	10,
  	WA_MaxWidth,	640,
  	WA_MaxHeight,	200,
  	TAG_DONE)))
  	    return(3L);

  GT_RefreshWindow(ModelsActiveWind->nn_Window, NULL);
  if (++ModelsNumWindows == 1)
    CreateModelsLists();
  GT_SetGadgetAttrs(ModelsGadgets[0], ModelsActiveWind->nn_Window, NULL,
 	GTLV_Labels, ModelsLists[0], TAG_END);
  RefreshGadgets(ModelsGadgets[0], ModelsActiveWind->nn_Window, NULL);
  return(0L);
}

void CloseModelsWindow(void)
{
  struct WindowNode *WindNode;
  struct Node *tempNode;

  if (tempNode = FindName(ModelsWindList, ModelsActiveWind->nn_Window->Title))
  {
    if (WindNode = FindWindowNode(ModelsWindList, ModelsActiveWind->nn_Window->Title))
    {
	if (ModelsTotalWindows == 1)
	  WindNode = NULL;
	else
	{
	  if (WindNode->ID == 1)
	    WindNode = FindWindowNode(ModelsWindList, tempNode->ln_Succ->ln_Name);
	  else
	    WindNode = FindWindowNode(ModelsWindList, tempNode->ln_Pred->ln_Name);
	}
	DelWindowNode(ModelsWindList, ModelsActiveWind->nn_Window->Title);
	if (ModelsActiveWind->nn_Window)
	  CloseWindow(ModelsActiveWind->nn_Window);
	if (WindNode)
	{
	  ModelsActiveWind = WindNode;
	  ReMakeWindowID(ModelsWindList);
	  WindowToFront(ModelsActiveWind->nn_Window);
	  ActivateWindow(ModelsActiveWind->nn_Window);
	}
    }
  }
}

int ModelsHandler(void)
{
  struct IntuiMessage	*msg;
  struct VAobject	VAObject;
  int running	= 1;
  int (*func)(struct VAobject VAObject);
  struct WindowNode *WindNode;
  ULONG class;
  UWORD code;

  while (msg=GT_GetIMsg(ModelsActiveWind->nn_Window->UserPort))
  {
    CopyMem((char *)msg, (char *)&ModelsMsg, (long)sizeof(struct IntuiMessage));
    class = msg->Class;
    code  = msg->Code;

    GT_ReplyIMsg(msg);
    switch(class)
    {

	  case IDCMP_MOUSEBUTTONS :
	    break;

	  case IDCMP_MOUSEMOVE :
	    break;

	  case IDCMP_GADGETDOWN :
	    break;

	  case IDCMP_INTUITICKS :
	    break;

	  case IDCMP_CLOSEWINDOW:
	     CloseModelsWindow();
	     if (--ModelsNumWindows == 0)
	     {
	         if (ModelsGList)
	            FreeGadgets(ModelsGList);
	     }
	     return(1);
	     break;

	  case IDCMP_ACTIVEWINDOW:
	  case IDCMP_INACTIVEWINDOW:
	    if (!IntuitionBase->ActiveWindow)
	    {
		ActivateWindow(ModelsActiveWind->nn_Window);
		break;
	    }
	    WindNode = FindWindowNode(ModelsWindList, IntuitionBase->ActiveWindow->Title);
	    if (WindNode)
		ModelsActiveWind = WindNode;
	    break;

	  case IDCMP_GADGETUP:
	    VAObject.va_Window = (struct Window *)ModelsActiveWind->nn_Window ;
	    VAObject.va_Gadget = (struct Gadget *)msg->IAddress;
	    VAObject.va_IntuiMsg = (struct IntuiMessage *)msg;
	    VAObject.va_Flags = 0;
	    VAObject.va_UserData = 0;
	    func = (void *)((struct Gadget *)ModelsMsg.IAddress)->UserData;
	    running =  func(VAObject);
	    break;

    }
  }
  return(running);
}

int ModelsMainHandler(void)
{
  int running = 1;
  ULONG windsig, signals;

  struct WindowNode *WindNode;
  int (*func)(void);
  while (running == 1)
  {
    windsig = 1L << ModelsActiveWind->nn_Window->UserPort->mp_SigBit;
    signals = Wait( windsig );
    if (signals & windsig)
    {
	    if (WindNode = FindWindowNode(ModelsWindList, ModelsActiveWind->nn_Window->Title))
	    {
	      func = (void *)WindNode->UserData;
	      running = func();
	      if (ModelsTotalWindows == 0)
		  running = 0;
	    }
    }
  }
  return(running);
}

int main(int argc, char *argv[])
{
  int rc;

  IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0);
  if (IntuitionBase == NULL)
    exit(0);
  if (!(GetPubScreen()))
  {
	ModelsWindList = GetNewList();
	for (rc=0; rc < 1; rc++)
	  ModelsLists[rc]=GetNewList();
          
        MultiSub();     //call sub program to open its window
        
	if (!(OpenModelsWindow("MultiProcess Demo")))
	  rc = ModelsMainHandler();
	for (rc=0; rc < 1; rc++)
	  FreeList(ModelsLists[rc]);
	FreeWindowList(ModelsWindList);
	ClosePubScreen();
  }
  if (IntuitionBase)
    CloseLibrary((struct Library *)IntuitionBase);
}
