//****************
//
// Name : VScreen.c
//
//****************

//**** Header files

//** OS3.1
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/GadgetClass.h>
#include <intuition/IntuitionBase.h>
#include <graphics/layers.h>

//** OS3.1 Prototypes
#include <clib/alib_protos.h>
#include <clib/intuition_protos.h>
#include <clib/layers_protos.h>
#include <clib/exec_protos.h>

//** OS3.1 Inline pragmas
#include <pragmas/intuition_pragmas.h>
#include <pragmas/layers_pragmas.h>
#include <pragmas/exec_pragmas.h>

//** ANSI header files
//#include <stdio.h>


//** Application Header files

#include "Librarian.h"
#include "VScreen.h"
#include "Win.h"
#include "Node.h"


//**** Local application Storage

static struct List VScreenList;

UBYTE VScreen;


//**** Private Show/Hide Functions


static struct Node *UnMapWindow(struct Window *window, UBYTE listno) {
  struct Node *n=NULL;

  if (n=(struct Node*)AllocVec(sizeof(struct Node),MEMF_CLEAR|MEMF_PUBLIC|MEMF_REVERSE)) {
   
    MoveSizeLayer(window->RPort->Layer,
		(MapX ) - window->LeftEdge,
		(MapY ) - window->TopEdge,
		(1) - window->Width,
		(1) - window->Height);
    n->ln_Name=(char *)window;
    n->ln_Pri=listno;
    AddTail(&VScreenList,n);
    window->RPort->Layer->Flags |= LAYERBACKDROP;
    window->Flags |= WFLG_BACKDROP;
  } // if
  return n;
} // UnMapWindow


static void MapWindow(struct Node *n) {
  struct Window *window;

  window=(struct Window *)n->ln_Name;
  MoveSizeLayer(window->RPort->Layer,
		(-MapX) + window->LeftEdge,
		(-MapY) + window->TopEdge  ,
		(-1) + window->Width,
		(-1) + window->Height);
  window->RPort->Layer->Flags &= ~LAYERBACKDROP;
  window->Flags &= ~WFLG_BACKDROP;

  Remove(n);
  FreeVec(n);
} // MapWindow


static struct Node *FindNode(char *n) {
  struct Node *myn;

  for ( myn=VScreenList.lh_Head; (myn->ln_Succ) ; myn=myn->ln_Succ )
    if (myn->ln_Name==n) return myn;
  return NULL;
} // FindNode


static void ExpungeNodes(BYTE pri) {
  struct Node *myn;
  struct Node *next;

  myn=VScreenList.lh_Head;
  while (myn->ln_Succ) {
    next=myn->ln_Succ;
    if ((0==pri)||(myn->ln_Pri==pri)) {
      Remove(myn);
      FreeVec(myn);
    }
    myn=next;
  } // while
} // ExpungeNodes


BOOL IsStickyWindow(struct Window *w) {
  struct MsgPort *mp;
  struct Task *task;

  if (w->Flags & WFLG_BACKDROP) return TRUE;
  if (w==OnGoWin) return TRUE;

  if (mp=w->UserPort) {
    if (task=(struct Task *)mp->mp_SigTask) {
      if (FindName(&Sticky,task->tc_Node.ln_Name)) return TRUE;
    }
  }

  return FALSE;
} // IfStickyWindow

//**** Public Functions


void InitVScreen(void) {
  NewList(&VScreenList);
  VScreen=1;
} // InitVScreen


void CloseVScreen(void) {
  ULONG          lock;
  struct Window *w;
  struct Node *n;
  struct Screen *wb;

  if (wb = LockPubScreen("Workbench")) {
    lock = LockIBase(0);
    w = wb->FirstWindow ;
    for (w=wb->FirstWindow ; w; w=w->NextWindow) {
      if (n=FindNode((char *)w)) {
	MapWindow(n);
      }
    } // for
    UnlockIBase(lock);
    VScreen=0;
    UnlockPubScreen(NULL, wb);
    ExpungeNodes(0);
  } // lock
  WindowToFront(OnGoWin);
} // CloseVScreen


void SwitchToScreen(int scrno) {
  ULONG          lock;
  struct Window *w;
  struct Node *n;
  struct Screen *wb;

  if (VScreen!=scrno) {
    if (wb = LockPubScreen("Workbench")) {
      lock = LockIBase(0);
      w = wb->FirstWindow ;
      for (w=wb->FirstWindow ; w; w=w->NextWindow) {
	if (n=FindNode((char *)w)) {
	  if (n->ln_Pri==scrno) {
	    MapWindow(n);
	  }
	} else {
	  if (!IsStickyWindow(w)) {
	    UnMapWindow(w,VScreen);
	  } // if !IsSticky
	} // if FindNode
      } // for
      UnlockIBase(lock);

      VScreen=scrno;
      ExpungeNodes(VScreen);
      UnlockPubScreen(NULL, wb);
    } // lock

    WindowToFront(OnGoWin);
  } //
} // SwitchToScreen


//****

struct Node *Iconify(void) {
  ULONG lock;
  struct Window *w;
  struct Window *act;
  struct Node *n=NULL;
  struct Screen *wb;

  if (wb = LockPubScreen("Workbench")) {
    lock = LockIBase(0);
    w = wb->FirstWindow ;
    act=((struct IntuitionBase *)IntuitionBase)->ActiveWindow;
    for (w=wb->FirstWindow ; w && (w!=act) ; w=w->NextWindow);

    if ( (w) && (0==FindNode((char *)w)) && (!IsStickyWindow(w)) ) {
      n=UnMapWindow(w,0);
    }

    UnlockIBase(lock);

    UnlockPubScreen(NULL, wb);
    WindowToFront(OnGoWin);
  } // lock
  return n;
} // Iconify


void UnIconify(struct Node *n) {
  ULONG lock;
  struct Window *w;
  struct Window *act;
  struct Screen *wb;

  if (wb = LockPubScreen("Workbench")) {
    lock = LockIBase(0);
    w = wb->FirstWindow ;
    act=(struct Window *)n->ln_Name;
    for (w=wb->FirstWindow ; w && (w!=act) ; w=w->NextWindow);

    if (w) {
      MapWindow(n);
      WindowToFront(act);
    } else { // already closed
      Remove(n);
      FreeVec(n);
    }

    UnlockIBase(lock);

    UnlockPubScreen(NULL, wb);
    WindowToFront(OnGoWin);
  } // lock
} // Uniconify

//**** End of file

