//****************
//
// Name : MenuAux.C
//
//****************


//******** Header Files

#include <exec/lists.h>

#include <intuition/gadgetclass.h>
#include <clib/intuition_protos.h>
#include <pragmas/intuition_pragmas.h>
extern struct Library *IntuitionBase;

#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <clib/graphics_protos.h>
#include <pragmas/graphics_pragmas.h>
extern struct Library *GfxBase;

#include <clib/exec_protos.h>
#include <pragmas/exec_pragmas.h>

#include <string.h>
#include "Promise.H"
#include "GrList.H"
#include "MenuAux.H"


//******** Public functions

MPMMData *MPMG_DetermineActiveMenu(MPMGData *mg, UWORD *Active) {
  MPMMData *mm;
  WORD X,Y;
  UWORD N=65535;

  mm=(MPMMData *)mg->ActiveMenus.lh_TailPred;
  for ( ; mm->Node.ln_Pred ; mm=(MPMMData *)mm->Node.ln_Pred) {

    // consider horizontal position
    X=mm->mwin->MouseX;
    if (X<0) continue;
    if (X>mm->mwin->Width) continue;

    // consider vertical position
    Y=mm->mwin->MouseY;
    if (Y<2) continue;
    if (Y>mm->mwin->Height-3) continue;

    // determine which is active
    N=(Y-2)/mm->ItemHeight;
    *Active=N;
    return mm;
  }

  *Active=N;
  return (MPMMData *)mg->ActiveMenus.lh_TailPred;
} // MPMG_DetermineActiveMenu


ULONG MPMG_EvalWidth(MPMMData *mm,struct RastPort *rp) {
  MPMMItem *node;
  ULONG max=0;
  ULONG cur;
  ULONG gutl=0;
  ULONG height=0;
  BOOL gutr=FALSE;

  node=(MPMMItem *)mm->Labels.lh_Head;
  for ( ; node->Node.ln_Succ ; ) {
    cur=TextLength(rp, node->Node.ln_Name, node->NumChars);
    if ((node->SubMenu)||(ITEM_IS_PROMT(node))) gutr=TRUE;
    if (node->Icon) {
      if (node->Icon->Width> gutl) gutl=node->Icon->Width;
      if (node->Icon->Height> height) height=node->Icon->Height;
    }
    if (cur>max) max=cur;
    node=(MPMMItem *)node->Node.ln_Succ;
  } // for
  if (gutr) max+=4+TextLength(rp,"»",1); // hack for now
  if (gutl) {
    gutl+=6;
    mm->GutterLeft=gutl;
  }
  if (height) {
    mm->ItemHeight=height+2;
  } else {
    mm->ItemHeight=0;
  }

  return max+mm->GutterLeft;
} // MPMG_EvalWidth


BOOL MPMG_MenuOpen(MPMGData *mg, MPMMData *mm, struct IBox *ib, struct GadgetInfo *gi, ULONG FWid) {
  LONG WL,WT,WH,WW,i;
  BOOL rc=FALSE;
  ULONG  Pen1, Pen2, TPen, BPen;
  ULONG Width, AW,YPos;
  struct RastPort *rp;
  MPMMItem *node;
  struct DrawInfo *dri= gi->gi_DrInfo;

  if ((mg->Flags & MPMG_LOOKNEW) && (mm->ItemHeight)) {
    mm->ItemHeight+=2;
  }

  if (mg->ItemHeight>mm->ItemHeight)
    mm->ItemHeight=mg->ItemHeight;

  mm->FitsItems= (gi->gi_Screen->Height - 4) / mm->ItemHeight;

  if (mm->Count>mm->FitsItems)
    WH=4 + (mg->FitsItems * mm->ItemHeight);
  else
    WH=4 + (mm->Count * mm->ItemHeight);
  WW=10+FWid;
  if (mg->MinWidth>WW) WW=mg->MinWidth;
  if (mg->MainMenu==mm) { // hang
    if (mg->Flags & MPMGF_DROP) WT=ib->Top+gi->gi_Domain.Height-4;
    else                       WT=ib->Top-WH;
    WL=ib->Left;
    if (ib->Width > WW) WW=ib->Width;
  } else { // hang right
    WL=ib->Left+(ib->Width*mg->MenuOverlap)/100;
    WT=ib->Top-(WH-ib->Height)/2;
    if ((WL+WW)>(gi->gi_Screen->Width)) { // hang left instead
      WL=ib->Left+ib->Width-WW-(ib->Width*mg->MenuOverlap)/100;
    }
  }

  mm->mwin = OpenWindowTags(NULL,
    WA_Left,            WL,
    WA_Top,             WT,
    WA_Width,           WW,
    WA_Height,          WH,
    WA_Activate,        FALSE,
    WA_CustomScreen,    gi->gi_Screen,
    WA_SizeGadget,      FALSE,
    WA_DragBar,         FALSE,
    WA_DepthGadget,     FALSE,
    WA_CloseGadget,     FALSE,
    WA_Borderless,      TRUE,
    WA_Flags,           0,
    WA_AutoAdjust,      TRUE,
    WA_RMBTrap,         TRUE,
    WA_SmartRefresh,    TRUE,
    WA_NoCareRefresh,   TRUE,
    TAG_END );
  if (mm->mwin) {
    mg->SelectDepth++;
    AddTail(&(mg->ActiveMenus),mm);
    mm->Active=65535;
    rc=TRUE;

    //
    rp=mm->mwin->RPort;
    if (mg->Flags & MPMG_LOOKNEW) {
      if (dri) {
	TPen=dri->dri_Pens[BARDETAILPEN];
	BPen=dri->dri_Pens[BARBLOCKPEN];
	Pen1=Pen2=dri->dri_Pens[BARDETAILPEN];
      } else {
	TPen=1; BPen=2; Pen1=1; Pen2=1;
      }
    } else {
      if (dri) {
	TPen=dri->dri_Pens[TEXTPEN];
	BPen=dri->dri_Pens[BACKGROUNDPEN];
	Pen1=dri->dri_Pens[SHINEPEN];
	Pen2=dri->dri_Pens[SHADOWPEN];
      } else {
	TPen=1; BPen=0; Pen1=2; Pen2=1;
      }
    }

//    WW=mm->mwin->Width;
//    WH=mm->mwin->Height;

    //**** Render body of menu
    SetRast( rp, BPen );
    SetAPen( rp, Pen1);
    Move( rp, 1, 1);
    Draw( rp, 1, -2L + WH);
    Draw( rp, 0, -1L + WH);
    Draw( rp, 0, 0 );
    Draw( rp, -1L + WW, 0 );
    SetAPen( rp, Pen2);
    Move( rp, -2L + WW, -2L + WH );
    Draw( rp, -2L + WW, 1);
    Draw( rp, -1L + WW, 0);
    Draw( rp, -1L + WW, -1L + WH);
    Draw( rp, 1, -1L + WH);

    //**** Render menu items
    SetAPen( rp, TPen);
    SetFont( rp, mg->Font );
    SetDrMd( rp, JAM1);

    AW=mm->mwin->Width-6-TextLength(rp,"»",1);

    Width = WW - 10 - mm->GutterLeft;
    node=(MPMMItem *)mm->Labels.lh_Head;
    YPos= 2+ mm->ItemHeight/2 + mg->Font->tf_Baseline/2;

    for (i=0; node->Node.ln_Succ ; i++ ) {
      if (i<mm->FitsItems) {
	Move(rp,5+mm->GutterLeft,YPos);
	Text(rp, node->Node.ln_Name, node->NumChars);
	if ( ITEM_IS_MENU(node) || ITEM_IS_PROMT(node) ) {
	  Move(rp,AW, YPos );
	  Text(rp, "»",1);
	}

	if (node->Icon) {
	  ULONG Width=node->Icon->Width;
	  ULONG Height=node->Icon->Height;
	  ULONG XPos=5+(mm->GutterLeft-Width)/2-2;
	  ULONG YPos=2+(mm->ItemHeight * i) + (mm->ItemHeight-Height)/2;
//          SetAPen(rp, 0);
//          RectFill(rp,XPos,YPos,XPos+Width-1,YPos+Height-1);
	  BltBitMapRastPort( node->Icon->bmap, 0, 0, rp,
		  XPos, YPos, Width, Height, 0xC0);
	  SetAPen( rp, TPen);
	}
      } // if
      YPos+=mm->ItemHeight;
      node=(MPMMItem *)node->Node.ln_Succ;
    } // for

  } // if

  return rc;
} // MPMG_MenuOpen


BOOL MPMG_MenuClose( Object *o, struct GadgetInfo *gi, MPMGData *mg, MPMMData *mm) {
  if (mm->mwin) {
    if (mm->Node.ln_Succ->ln_Succ) MPMG_MenuClose(o,gi,mg,(MPMMData *)mm->Node.ln_Succ);
    CloseWindow(mm->mwin);
    mm->mwin = NULL;
    Remove(mm);
    mg->SelectDepth--;
  }
  if ( (mm->ActiveNode) && ( ITEM_IS_PROMH(mm->ActiveNode) || ITEM_IS_PROMR(mm->ActiveNode) )) {
    CancelPromise(o,gi,mm->ActiveNode);
  }
  if (mm!=mg->MainMenu) {
    mm=(MPMMData *)(mm->Node.ln_Pred);
    if ( ITEM_IS_PROMH(mm->ActiveNode) || ITEM_IS_PROMR(mm->ActiveNode) ) {
      CancelPromise(o,gi,mm->ActiveNode);
    }
  }
  return TRUE;
} // MPMG_MenuClose


BOOL MPMG_MenuRenderItem(MPMGData *mg, MPMMData *mm, struct DrawInfo *dri, BOOL active) {
  ULONG  TPen, BPen, Pen1, Pen2;
  struct RastPort *rp=mm->mwin->RPort;
  MPMMItem *node;
  ULONG i,YPos, XPos;
  ULONG Top, Bottom, Width, Height;

  if (65535==mm->Active) return FALSE;
  SetDrMd(rp,JAM1);

  Top = 2 + mm->Active * mm->ItemHeight;
  Bottom = Top + mm->ItemHeight - 1;

  if (TRUE==active) {
    node=(MPMMItem *)mm->Labels.lh_Head;
    for (i=0; i<mm->Active ; i++ ) node=(MPMMItem *)node->Node.ln_Succ;
    mm->ActiveNode=node;
    if (mg->SelectPath)
      if (mg->SelectDepth<=mg->SelectPathSize) (mg->SelectPath)[mg->SelectDepth-1]=mm->Active;
    if (ITEM_IS_LABEL(node)) active=FALSE;
    if (mg->Flags & MPMG_LOOKNEW) {
      if (dri) {
	TPen=dri->dri_Pens[BARBLOCKPEN];
	BPen=dri->dri_Pens[BARDETAILPEN];
      } else {
	TPen=2; BPen=1;
      }
    } else {
      if (dri) {
	TPen=dri->dri_Pens[TEXTPEN];
	BPen=dri->dri_Pens[FILLPEN];
	Pen1= dri->dri_Pens[SHADOWPEN];
	Pen2= dri->dri_Pens[SHINEPEN];
      } else {
	TPen=1; BPen=3;
	Pen1=1; Pen2=2;
      }
    }
  } // if TRUE==active
  if (FALSE==active) {
    node=mm->ActiveNode;
    if (mg->Flags & MPMG_LOOKNEW) {
      if (dri) {
	TPen=dri->dri_Pens[BARDETAILPEN];
	BPen=dri->dri_Pens[BARBLOCKPEN];
      } else {
	TPen=1; BPen=2;
      }
    } else {
      if (dri) {
	TPen=dri->dri_Pens[TEXTPEN];
	BPen=dri->dri_Pens[BACKGROUNDPEN];
      } else {
	TPen=1; BPen=0;
      }
    }
  }

  //**** Blank background

  SetAPen(rp, BPen);
  if (mg->Flags&MPMG_LOOKX) {
    RectFill(rp,3, Top, mm->mwin->Width-4, Bottom);
    if (TRUE==active) {
      SetAPen( rp, Pen1);
      Move( rp, 3, Bottom);
      Draw( rp, 3, Top );
      Draw( rp, mm->mwin->Width-4, Top );
      SetAPen( rp, Pen2);
      Draw( rp, mm->mwin->Width-4, Bottom );
      Draw( rp, 4, Bottom );
    }
  } else {
    RectFill(rp,4, Top, mm->mwin->Width-5, Bottom);
  }

  //**** Render item

//  SetFont(rp,mg->Font);
  SetAPen(rp, TPen);
  YPos= 2 + mm->ItemHeight/2 + mg->Font->tf_Baseline/2 + (mm->ItemHeight * mm->Active);
  Move(rp,5+mm->GutterLeft,YPos);
  Text(rp, node->Node.ln_Name, node->NumChars);
  if ( (ITEM_IS_MENU(node)) || (ITEM_IS_PROMT(node)) ) {
    Move(rp,mm->mwin->Width-6-TextLength(rp,"»",1),YPos);
    Text(rp,"»",1);
  }

  //**** Render Icon
  if (node->Icon) {
    Width=node->Icon->Width;
    Height=node->Icon->Height;
    XPos=5+(mm->GutterLeft-Width)/2-2;
    YPos=2+(mm->ItemHeight * mm->Active) + (mm->ItemHeight-Height)/2;
    if (TRUE==active) {
      SetAPen(rp, 0);
      RectFill(rp,XPos,YPos,XPos+Width-1,YPos+Height-1);
      BltBitMapRastPort( node->Icon->bmap, Width , 0, rp,
	XPos, YPos, Width, Height, 0xC0);
    } else {
      BltBitMapRastPort( node->Icon->bmap, 0 , 0, rp,
	XPos, YPos, Width, Height, 0x60);
    }
  }

  return TRUE;
} // MPMG_MenuRenderItem


//******** End of file

