#include <exec/memory.h>
#include <graphics/displayinfo.h>
#include <graphics/modeid.h>
#include <string.h>

#include <proto/exec.h>
#include <proto/graphics.h>
#include <clib/alib_protos.h>

#include "/include/server.h"

extern UBYTE briLevel;

struct List *ModeList;
struct ModeNode *DisplayNode;
ULONG DisplayID = PAL_MONITOR_ID;

char DefaultModeName[DISPLAYNAMELEN];


void DeleteModeList( void )
{
struct ModeNode *ModeNode;

while (ModeList->lh_Head->ln_Succ)
	{
	ModeNode=(struct ModeNode *)ModeList->lh_Head;
	RemHead (ModeList);
	FreeVec( ModeNode );
	}
FreeVec( ModeList );
}


struct List *CreateModeList(void)
{
UWORD Index = 0;
ULONG NewDisplID;
struct DimensionInfo DimInfo;
struct NameInfo NameInfo;
struct ModeNode *NewNode;

if ( ModeList = AllocVec( sizeof(struct List), MEMF_PUBLIC ) )
	NewList( ModeList );
else
	return( NULL );

NewDisplID=INVALID_ID;

while ( ( NewDisplID = NextDisplayInfo( NewDisplID ) ) != INVALID_ID )
	if ( ( NewDisplID & MONITOR_ID_MASK ) && ( !ModeNotAvailable( NewDisplID ) ) )
		if ( GetDisplayInfoData( NULL, (UBYTE *)&DimInfo, sizeof(struct DimensionInfo), DTAG_DIMS, NewDisplID ) )
			if ( GetDisplayInfoData( NULL, (UBYTE *)&NameInfo, sizeof(struct NameInfo), DTAG_NAME, NewDisplID ) )
				if ( NewNode = AllocVec( sizeof(struct ModeNode), MEMF_CLEAR ) )
				{
				NewNode->mn_Node.ln_Name = NewNode->mn_Name;
				NewNode->mn_DisplayID = NewDisplID;
				NewNode->mn_Index = Index++;
				strcpy( NewNode->mn_Name, NameInfo.Name );
				AddTail( ModeList, (struct Node *)NewNode );
				}

if ( !ModeList->lh_Head->ln_Succ )
	DisplayID = 0L;

if ( DisplayID == INVALID_ID )
	{
	if ( NewNode = (struct ModeNode *)FindName( ModeList, DefaultModeName ) )
		DisplayID = NewNode->mn_DisplayID;
	else
		DisplayID = PAL_MONITOR_ID;
	}

return( ModeList );
}


void GetDisplayNodeFromID( void )
{
if ( DisplayID != 0L )
	{
	DisplayNode = (struct ModeNode *)ModeList->lh_Head;

	while( DisplayNode && DisplayNode->mn_DisplayID != DisplayID )
		DisplayNode = (struct ModeNode *)DisplayNode->mn_Node.ln_Succ;

	if ( !DisplayID || !DisplayNode )
		{
		DisplayNode = (struct ModeNode *)ModeList->lh_Head;
		DisplayID = DisplayNode->mn_DisplayID;
		}
	}
}


void GetDisplayNodeFromName( void )
{
if ( ModeList->lh_Head->ln_Succ )
	{
	if ( (*DefaultModeName != 0) && (DisplayNode = (struct ModeNode *)FindName( ModeList, DefaultModeName )) )
		DisplayID = DisplayNode->mn_DisplayID;
	else
		DisplayID = PAL_MONITOR_ID;
	}
	else
		DisplayID = 0L;
}


void GetDisplayIDFromNode( UWORD Index )
{
DisplayNode = (struct ModeNode *)ModeList->lh_Head;

while( DisplayNode && DisplayNode->mn_Index != Index )
	DisplayNode = (struct ModeNode *)DisplayNode->mn_Node.ln_Succ;

DisplayID = DisplayNode->mn_DisplayID;
}


struct DisplayIDInformation *AllocDisplayIDInformation( ULONG whichDisplayID )
{
struct DisplayIDInformation *diinfo;

if ( diinfo = AllocVec( sizeof(struct DisplayIDInformation), MEMF_PUBLIC ) )
	{
	if ( GetDisplayInfoData( NULL, (UBYTE *)&diinfo->di_DisplayInfo, sizeof(struct DisplayInfo), DTAG_DISP, whichDisplayID ) )
		if ( GetDisplayInfoData( NULL, (UBYTE *)&diinfo->di_DimensionInfo, sizeof(struct DimensionInfo), DTAG_DIMS, whichDisplayID ) )
				if ( GetDisplayInfoData( NULL, (UBYTE *)&diinfo->di_MonitorInfo, sizeof(struct MonitorInfo), DTAG_MNTR, whichDisplayID ) )
					{
					diinfo->di_Brightness = briLevel;
					return( diinfo );
					}
	FreeVec( diinfo );
	}
return( NULL );
}
