#include "sysheaders.h"
#include "cdpanel.h"
#include "CompactPlayer.h"

/********************************************************
 * CD Index editor
 */

struct Window *ConfWin;
Object *ConfWinObj;
struct Gadget *ConfLayout;
struct List *DeviceList;
struct List *UnitList;

STRPTR Devs[64];
STRPTR Units[8];
LONG UnitIDs[8];

static ULONG device;
static ULONG unit;

UBYTE UnitNames[7][26];

static STRPTR AvoidNames[] = 
{
	"audio.device",         /* System devices we want to skip */
	"clipboard.device",
	"console.device",
	"gameport.device",
	"input.device",
	"keyboard.device",
	"parallel.device",
	"printer.device",
	"ramdrive.device",
	"serial.device",
	"timer.device",
	"trackdisk.device",
	"mfm.device",

	"bootdisk.device",      /* Other devices that we don't want */
	"modem0.device",
	"modem1.device",
	"modem2.device",
	"modem3.device",
	"pit.device",
	"duart.device",
	"ppp.device",
	"slip.device",
	"cslip.device",
	"rhslip.device",
	"rhcslip.device",
	"a2060.device",
	"a2065.device",

	NULL
};

BOOL
AvoidDevice(STRPTR s)
{
	STRPTR *a = AvoidNames;
	
	while (*a)
	{
		if (!strcmp(*a++, s))
			return TRUE;
	}
	return FALSE;
}

struct List *
MakeDeviceList(void)
{
	struct Node *n;
	LONG i = 0;

	Forbid();
	
	for (n = SysBase->DeviceList.lh_Head; n->ln_Succ; n = n->ln_Succ)
	{
		if (!AvoidDevice(n->ln_Name))
			Devs[i++] = n->ln_Name;
	}
	Permit();
	Devs[i] = NULL;
	
	return BrowserNodesA(Devs);
}

struct List *
MakeUnitList(STRPTR device)
{
	struct MsgPort *mp;
	struct IOStdReq *io;
	struct List *l;
	BOOL CD[8];
	
	Units[0] = NULL;
	
	if (mp = CreateMsgPort())
	{
		if (io = CreateIORequest(mp, sizeof(struct IOStdReq)))
		{
			LONG i, j = 0;
			static SCSICMD6 command = { SCSI_INQUIRY };
			static struct SCSICmd ScsiCmd;
			UBYTE data[80];
			
			if (ConfWinObj)
				SetAttrs(ConfWinObj, WA_Title, GS(PLEASE_WAIT), TAG_END);
			
			for (i = 0; i < 8; i++)
			{
				if (!OpenDevice(device, i, (struct IORequest *)io, 0L))
				{
					command.b4 = 40;
					
					ScsiCmd.scsi_Command = (UBYTE *)&command;
					ScsiCmd.scsi_CmdLength = sizeof(command);
					ScsiCmd.scsi_Data = (UWORD *)data;
					ScsiCmd.scsi_Length = sizeof(data)/2;
					ScsiCmd.scsi_Flags = SCSIF_READ;
					
					io->io_Command = HD_SCSICMD;
					io->io_Data = &ScsiCmd;
					io->io_Length = sizeof(ScsiCmd);
			
					DoIO((struct IORequest *)io);
					
					if (!io->io_Error)
						Sprintf(UnitNames[i], "%-8.8s %-16.16s", &data[8], &data[16]);
					else
						Sprintf(UnitNames[i], GS(ERROR));
					
					Units[j] = UnitNames[i];
					CD[j] = (BOOL)(((data[0] & 0x1f) == 0x05) ? TRUE : FALSE); /* is a CD-ROM */
					UnitIDs[j++] = i;

					CloseDevice(io);
				}
			}
			Units[j] = NULL;
		
			if (ConfWinObj)
				SetAttrs(ConfWinObj, WA_Title, GS(CONFIGURATION), TAG_END);
			
			DeleteIORequest(io);
		}
		DeleteMsgPort(mp);
	}
	l = BrowserNodesA(Units);
	{
		struct Node *n = l->lh_Head;
		LONG i = 0;
		
		while (n->ln_Succ)
		{
			if (CD[i])
				SetListBrowserNodeAttrs(n, LBNA_Flags, LBFLG_CUSTOMPENS, LBNCA_FGPen, 2, TAG_END);
		
			n = n->ln_Succ; i++;
		}
	}
	return l;
}

struct Window *
OpenConfWindow(ULONG X, ULONG Y)
{
	if (ConfWin)
		return ConfWin;

	/* Two listviews with a button below the left side list */
		
	ConfLayout = HGroupObject, LAYOUT_SpaceOuter, TRUE,
		GA_DrawInfo, Dri,
		LAYOUT_DeferLayout, TRUE,
		StartVGroup,
			StartMember, GList[G_Device] = ListBrowserObject,
				LISTBROWSER_Labels, &dummyList,
				LISTBROWSER_ShowSelected, TRUE,
				GA_RelVerify, TRUE,
				GA_ID, G_Device,
				End,
				CHILD_MinWidth, ScreenFont->tf_XSize * 12,
			StartMember, GList[G_Select] = ButtonObject,
				GA_Text, GS(B_USE_THIS),
				GA_ID, G_Select,
				GA_RelVerify, TRUE,
				End,
				CHILD_WeightedHeight, 0,
			EndGroup,
			CHILD_WeightedWidth, 0,
		StartMember, GList[G_Unit] = ListBrowserObject,
			LISTBROWSER_Labels, &dummyList,
			LISTBROWSER_ShowSelected, TRUE,
			GA_RelVerify, TRUE,
			GA_ID, G_Unit,
			GA_Disabled, TRUE,
			End,
			CHILD_MinHeight, ScreenFont->tf_YSize * 4,
			CHILD_MinWidth, ScreenFont->tf_XSize * 16,
		End;
	
	if (ConfLayout)
	{
		if (ConfWinObj = WindowObject,
				WA_DepthGadget,		TRUE,
				WA_CloseGadget,		TRUE,
				WA_DragBar,			TRUE,
				WA_Activate,		TRUE,
				WA_SizeGadget,		TRUE,
				WA_Top,				Y,
				WA_Left,			X,
				WA_PubScreen,		Scr,
				WA_Title,			GS(CONFIGURATION),
				WA_ScreenTitle,		GS(TITLE_COPYRIGHT),
				WA_AutoAdjust, 		TRUE,
				WA_SimpleRefresh, 	TRUE,
				WINDOW_Layout, 		ConfLayout,
				WINDOW_AppPort,		AppPort,
				WINDOW_SharedPort,	WinPort,
				TAG_END))
		{
			LONG i;
			
			ConfWin = CA_OpenWindow(ConfWinObj);
			
			DeviceList = MakeDeviceList();
			for (i = 0; Devs[i]; i++)
			{
				if (!strcmp(Device, Devs[i]))
					break;
			}
			if (!Devs[i])
				i = 0;
			SetGadgetAttrs(GList[G_Device], ConfWin, NULL, LISTBROWSER_Labels, DeviceList, LISTBROWSER_Selected, i, TAG_END);
			device = i;

			if (strcmp("cd.device", Device))
			{
				UnitList = MakeUnitList(Devs[i]);
				for (i = 0; i > 7 || UnitIDs[i] == Unit; i++);
				SetGadgetAttrs(GList[G_Unit], ConfWin, NULL, LISTBROWSER_Labels, UnitList, GA_Disabled, FALSE, LISTBROWSER_Selected, i, TAG_END);
			}
			unit = i;
		
			return ConfWin;
		}
		DisposeObject(ConfLayout);
		ConfLayout = NULL;
	}
	ErrorMsg(GS(GUI_FAIL));
}

void
CloseConfWindow(void)
{
	if (ConfWinObj)
	{
		DisposeObject(ConfWinObj);
		ConfWin = NULL;
		ConfWinObj = NULL;
		ConfLayout = NULL;
		memset(&GList[G_Device], 0, (ULONG)&GList[GG_MAX3]-(ULONG)&GList[G_Device]);
	}
	FreeBrowserNodes(DeviceList);
	DeviceList = NULL;
	FreeBrowserNodes(UnitList);
	UnitList = NULL;
}

void
ConfWindowIDCMP(void)
{
	BOOL close = FALSE;
	ULONG result;
	WORD code;
	
	if (!ConfWinObj)
		return;
		
	while ((result = CA_HandleInput(ConfWinObj,&code)) != WMHI_LASTMSG)
	{
		/* CA_HandleInput (aka. WM_HANDLEINPUT) will translate keyboard events
		 * into GADGETUPs on its own */
		switch (result & WMHI_CLASSMASK)
		{
		case WMHI_CLOSEWINDOW:
			close = TRUE;
			break;
			
		case WMHI_GADGETUP:
			switch(result & WMHI_GADGETMASK)
			{
			case G_Device:
				if (code != device)
				{
					if (SetGadgetAttrs(GList[G_Unit], ConfWin, NULL, LISTBROWSER_Labels, &dummyList, GA_Disabled, TRUE, TAG_END))
						RefreshGList(GList[G_Unit], ConfWin, NULL, 1);
					FreeBrowserNodes(UnitList);
					if (strcmp("cd.device", Devs[code]))
					{
						UnitList = MakeUnitList(Devs[code]);
						if (SetGadgetAttrs(GList[G_Unit], ConfWin, NULL, LISTBROWSER_Labels, UnitList, GA_Disabled, FALSE, TAG_END))
							RefreshGList(GList[G_Unit], ConfWin, NULL, 1);
					}
					else
					{
						UnitList = NULL;
						memset(UnitIDs, 0, sizeof(UnitIDs));
						unit = 0;
					}
					device = code;
				}
				break;

			case G_Unit:
				unit = code;
				break;
			
			case G_Select:
				Device = Devs[device];
				Unit = UnitIDs[unit];
				if (Init_Device() == 0)
					close = TRUE;
				break;
			}
		}
	}
	if (close)
		CloseConfWindow();
}
