/*
 * FullMonitorData is a program, that displays all available data
 *                 to a given monitor ID.
 *
 *                 You can choose the ID via the ASL-ScreenMode request
 *                 or the ScreenMode request from the vilintuisup.library
 *
 * Datum:          14. Juni 1993
 * Autor           David Göhler
 * Firma           VillageTronic Marketing GmbH
 *
 * Compiler        DICE 2.06.37 (Vorsicht AutoInit, dieser Code schmiert mit SAS ab!)
 */

#include <graphics/monitor.h>
#ifndef GRAPHICS_MODEID_H
#include <graphics/modeid.h>
#endif
#include <graphics/displayinfo.h>
#include <graphics/gfx.h>
#include <graphics/displayinfo.h>
#include <libraries/asl.h>
#include <intuition/intuitionbase.h>

#include <clib/graphics_protos.h>
#include <clib/asl_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>

#include <string.h>

#include "vilintuisup.h"
#include "vilintuisup/vilintuisup_protos.h"


struct Library *VilIntuiBase;
struct Library *GfxBase;
struct Library *AslBase;
struct IntuitionBase *IntuitionBase;

void PrintDisplayInfo(struct DisplayInfo *di)
{
   char fb[300] = ""; // flagbuffer
   register ULONG f = di->PropertyFlags;

   Printf("\x1b[4mDisplayInfo-Data:\x1b[0m\n");
   Printf("\tMode is                  : %savailable\n",di->NotAvailable ? "not " : "");

   if (f & DIPF_IS_LACE) strcat(fb," lace");
   if (f & DIPF_IS_DUALPF) strcat(fb," dualpf");
   if (f & DIPF_IS_PF2PRI) strcat(fb," pf2pri");
   if (f & DIPF_IS_HAM) strcat(fb," ham");
   if (f & DIPF_IS_ECS) strcat(fb," ecs");
   if (f & DIPF_IS_AA) strcat(fb," aa");
   if (f & DIPF_IS_PAL) strcat(fb," pal");
   if (f & DIPF_IS_SPRITES) strcat(fb," sprites");
   if (f & DIPF_IS_GENLOCK) strcat(fb," genlock");
   if (f & DIPF_IS_WB) strcat(fb," wb");
   if (f & DIPF_IS_DRAGGABLE) strcat(fb," draggable");
   if (f & DIPF_IS_PANELLED) strcat(fb," panelled");
   if (f & DIPF_IS_BEAMSYNC) strcat(fb," beamsync");
   if (f & DIPF_IS_EXTRAHALFBRITE) strcat(fb," extrahalfbrite");
   if (f & DIPF_IS_SPRITES_ATT) strcat(fb," sprites_att");
   if (f & DIPF_IS_SPRITES_CHNG_RES) strcat(fb," sprites_chng_res");
   if (f & DIPF_IS_SPRITES_BORDER) strcat(fb," sprites_border");
   if (f & DIPF_IS_SCANDBL) strcat(fb," scandbl");
   if (f & DIPF_IS_SPRITES_CHNG_BASE) strcat(fb," sprites_chng_base");
   if (f & DIPF_IS_SPRITES_CHNG_PRI) strcat(fb," sprites_chng_pri");
   if (f & DIPF_IS_DBUFFER) strcat(fb," dbuffer");
   if (f & DIPF_IS_PROGBEAM) strcat(fb," progbeam");
   if (f & DIPF_IS_FOREIGN) strcat(fb," foreign");
   Printf("\tFlags                    :%s\n",fb);
   Printf("\tResolution in Ticks/Pixel: (%ld,%ld)\n",di->Resolution.x,di->Resolution.y);
   Printf("\tPixelSpeed in ns         : %ld\n",di->PixelSpeed);
   Printf("\tnumber standard sprites  : %ld\n",di->NumStdSprites);
   Printf("\tResolution Sprites t/p   : (%ld,%ld)\n",di->SpriteResolution.x,di->SpriteResolution.y);
   Printf("\tNumber of Bits in RGB    : (%ld,%ld,%ld)\n",di->RedBits, di->GreenBits,
							 di->BlueBits);
   PutStr("\n");
}

PrintFour(char *String, struct Rectangle *ra)
{
   Printf(String,ra->MinX,ra->MinY,ra->MaxX,ra->MaxY);
}

void PrintDimensionInfo(struct DimensionInfo *di)
{
   Printf("\x1b[4mDimensionInfo-Data:\x1b[0m\n");
   Printf("\tColorDepth               : %ld\n",di->MaxDepth);
   Printf("\tMin Width/Height         : (%ld,%ld)\n",di->MinRasterWidth, di->MinRasterHeight);
   Printf("\tMax Width/Height         : (%ld,%ld)\n",di->MaxRasterWidth, di->MaxRasterHeight);
   PrintFour("\tStandard Res             : (%ld,%ld,%ld,%ld)\n",&(di->Nominal));
   PrintFour("\tMaxOverScan Res          : (%ld,%ld,%ld,%ld)\n",&(di->MaxOScan));
   PrintFour("\tVideoOverScan Res        : (%ld,%ld,%ld,%ld)\n",&(di->VideoOScan));
   PrintFour("\tTextOverScan Res         : (%ld,%ld,%ld,%ld)\n",&(di->TxtOScan));
   PrintFour("\tStandardOverScan Res     : (%ld,%ld,%ld,%ld)\n\n",&(di->StdOScan));
}

void PrintMonitorInfo(struct MonitorInfo *mi)
{
   struct MonitorSpec *ms = mi->Mspc;
   ULONG Hertz = 1000000000 / (280 * mi->TotalRows * mi->TotalColorClocks);

   Printf("\x1b[4mMonitorInfo-Data:\x1b[0m\n");
   Printf("\tMonitor file name        : %s\n",ms->ms_Node.xln_Name);
   Printf("\tHertz                    : %ld\n",Hertz);
   Printf("\tLine Frequency           : %ld\n",1000000000 / (280 * mi->TotalColorClocks));
   Printf("\tViewPosition             : (%ld,%ld)\n",mi->ViewPosition.x, mi->ViewPosition.y);
   Printf("\tViewResolution t/p       : (%ld,%ld)\n",mi->ViewResolution.x, mi->ViewResolution.y);
   PrintFour("\tViewPositionRange        : (%ld,%ld,%ld,%ld)\n",&(mi->ViewPositionRange));
   Printf("\tTotalRows (Scanlines)    : %ld\n",mi->TotalRows);
   Printf("\tTotalClocks (280ns)      : %ld\n",mi->TotalColorClocks);
   Printf("\tMinRow                   : %ld\n",mi->MinRow);
   PutStr("\tCompability              : ");
   if (mi->Compatibility == MCOMPAT_MIXED)
   {  PutStr("mix with others\n"); }
   else if (mi->Compatibility == MCOMPAT_SELF)
   {  PutStr("only with same monitor\n"); }
   else if (mi->Compatibility == MCOMPAT_NOBODY)
   {  PutStr("only one viewport at a time\n"); }
   else
   {  PutStr("<unknown>\n"); }
   PrintFour("\tDefaultViewPosition      : (%ld,%ld,%ld,%ld)\n",&(mi->DefaultViewPosition));
   Printf("\tPreferredModeID          : %lx\n\n",mi->PreferredModeID);
}


void PrintNameInfo(char *name, ULONG id)
{
   Printf("\x1b[4mNameInfo-Data:\x1b[0m\n");
   Printf("\tName                     : %s\n",name );
   Printf("\tMonitorID                : %lx\n\n", id );
}

LONG GetScreenMode(struct Screen *s,struct TagList *tl, ULONG *Farben)
{
   LONG retcode = -1L;
   struct ScreenModeRequester *smr = 0L;

   if (s == 0) return retcode;

   if (AslBase = OpenLibrary(AslName,38L))
   {
      if (smr = AllocAslRequestTags(ASL_ScreenModeRequest,
		       ASLSM_Screen, s,
		       ASLSM_TitleText, "Please select a ScreenMode:",
		       ASLSM_PositiveText, "O.K.",
		       ASLSM_NegativeText, "Cancel",
		       ASLSM_DoDepth, Farben != 0 ? TRUE : FALSE,
		       ASLSM_PropertyFlags, 0, // DIPF_IS_WB,
		       ASLSM_PropertyMask, DIPF_IS_FOREIGN,
		       ASLSM_MinWidth, 640L,
		       ASLSM_MinHeight, 400L,

		       ASLSM_InitialWidth, 260L,
		       ASLSM_InitialHeight, (s->Height-(s->BarHeight+2)),
		       ASLSM_InitialLeftEdge, (s->Width-260) / 2,
		       ASLSM_InitialTopEdge, s->BarHeight,
		       TAG_DONE))
      {
	 if (AslRequest((APTR)smr,tl)) // wenn, dann hat der User gewählt
	 {  retcode = smr->sm_DisplayID;
	    if (Farben)
	    {  *Farben = smr->sm_DisplayDepth; }
	 }
	 FreeAslRequest(smr);
      }
      else
      {  PutStr("Can't open ScreenModeRequest\n");
      }
      CloseLibrary(AslBase);
      AslBase = 0L;
   }
   else
   {  PutStr("Can't open asl.library version 38 or higher\n");
   }

   return retcode;
}

int main(int argc, char *argv[])
{
   struct MonitorInfo   mi;
   struct NameInfo      ni;
   struct DimensionInfo dim;
   struct DisplayInfo   dis;
   DisplayInfoHandle    Handle;
   ULONG  MonitorID;
   BOOL   picasso = FALSE;

   if (argc >= 2)
   {   if ((strnicmp(argv[1],"P",1) == 0) || (strnicmp(argv[1],"Picasso",7) == 0))
       {
	  picasso = TRUE;
       } else
       if ((strncmp(argv[1],"?",1) == 0))
       {  Printf("%s [PICASSO]\n",argv[0]);
	  return 0;
       }
   }

   /*
    *    some libraries are always necessary.
    *    if the vilintuisup.library can't be opened, there might be
    *    no Picasso-II builtin.
    */

   if (VilIntuiBase = OpenLibrary("vilintuisup.library",0))
   {
     if (IntuitionBase = OpenLibrary("intuition.library",0))
     {
       if (GfxBase = OpenLibrary("graphics.library",0))
       {
	 if (picasso)
	 {
	    MonitorID = VillageModeRequest(0L);
	 }
	 else
	 {
	    if (IntuitionBase = OpenLibrary("intuition.library",0))
	    {  ULONG lock;
	       struct Screen *s;

	       lock = LockIBase(0L);
	       s = IntuitionBase->FirstScreen;
	       UnlockIBase(lock);
	       MonitorID = GetScreenMode(s,0L,0L);
	    }
	 }

	 if (MonitorID != INVALID_ID)
	 {
	    if (!ModeNotAvailable (MonitorID))
	    {
	       if (Handle = FindDisplayInfo(MonitorID))
	       {
		   if ( GetDisplayInfoData (Handle,&ni, sizeof(ni), DTAG_NAME,0))
		   {  PrintNameInfo(ni.Name,MonitorID); }
		   else
		   {  PrintNameInfo("<none>",MonitorID); }
		   if ( GetDisplayInfoData (Handle,&dim,sizeof(dim),DTAG_DIMS,0))
		   {  PrintDimensionInfo(&dim); }
		   if ( GetDisplayInfoData (Handle,&dis,sizeof(dis),DTAG_DISP,0))
		   {  PrintDisplayInfo(&dis); }
		   if ( GetDisplayInfoData (Handle,&mi,sizeof(mi),DTAG_MNTR,0))
		   {  PrintMonitorInfo(&mi); }
	       }
	    }
	 }
	 CloseLibrary(GfxBase);

       }
       CloseLibrary(IntuitionBase);

     }
     CloseLibrary(VilIntuiBase);

   }
   else
   {  PutStr("can't open \"vilintuisup.library\"\n");
   }

   return 0;
}


