//#include "/ModePro.h"
//#include "mpp.h"
#include "mppexterns.h"
#include <stdio.h>

extern struct LG_Control *GadControl;
extern LONG ActivePen;
extern BOOL ClosePrefs;
extern struct Window *Win;
extern UWORD defaultpens[];
extern UWORD NumDriPens;
extern STRPTR MiscText[];
extern ULONG ListToCyc[];
extern  WORD CurrentList_2,
             CurrentList;
extern  LONG LVActive,
             NodeCnt;
extern ULONG ActivateStrGad;
extern UBYTE EnvFile[],
             EnvArcFile[];
extern struct MPSem   *MPSem;
extern struct List ForcedEditList;
extern struct MPMessage *ForcedEditMsg;
extern UBYTE    filename[513];
extern struct Window   *Win;

void ReturnFEMsg(ULONG Code);
BOOL SetDNFlag(struct DefaultNode *N, ULONG Flag, BOOL Set, BOOL Keyed);


void GD_Type(LONG Code)
{
  if(Code>MAX_TYPE)
    Code=0;
  else
    if(Code<0)
      Code=MAX_TYPE;

  CurrentList_2=Code;
  CurrentList=ListToCyc[Code];
  LVActive=0;
  UpdateGadgets();
}

struct DefaultNode *GD_New(void)
{
  struct DefaultNode *n;
  ULONG l;
  
  if(n=AllocDefaultNode(0))
  {
    if(CurrentList!=MPSEM_PLIST_SCREENMODES)
      n->Def_Node.ln_Name=CopyString(MiscText[ITEM_NEW_NAME], MEMF_CLEAR | MEMF_PUBLIC);
    else
      n->Def_Node.ln_Name=GetModeName(0);
      
    n->Type=CurrentList;
    n->OverscanType=1;
    for(l=0;l<NumDriPens;l++)
      n->Pens[l]=defaultpens[l];
  
    ObtainSemaphore(&MPSem->NodeSem);
    LG_SetGadgetAttrs(GadControl,GD_LIST,
                     GTLV_Labels      ,~0,
                     GTLV_Selected    ,0,
                     TAG_DONE);
    AddHead(&MPSem->PromotionList[CurrentList],(struct Node *)n);
    LVActive=0;
        
    ReleaseSemaphore(&MPSem->NodeSem);
    UpdateGadgets();
    ActivateStrGad=GD_NAME;
  } 
  return(n);
} 

void GD_Save(void)
{
  ClosePrefs=TRUE;
  ObtainSemaphore(&MPSem->NodeSem);
  PrefSaveFile(EnvArcFile);
  PrefSaveFile(EnvFile);
  ReleaseSemaphore(&MPSem->NodeSem);
}

void GD_Use(void)
{
  ClosePrefs=TRUE;
  PrefSaveFile(EnvFile);
}

void GD_Cancel(void)
{
  ObtainSemaphore(&MPSem->NodeSem);
  LG_SetGadgetAttrs(GadControl,GD_LIST,
                    GTLV_Labels,~0,TAG_DONE);
  FreeAllDefLists(MPSem->PromotionList);
  PrefLoadFile(EnvFile);
  ReleaseSemaphore(&MPSem->NodeSem);
//  LVActive=0
  ClosePrefs=TRUE;
}

LONG SSecs=0;SMicros=0;
struct DefaultNode *DCNode;

void GD_List(LONG Item, BOOL Keyed, struct IntuiMessage *IMsg)
{
  struct DefaultNode *n;
  BOOL fullupdate=0;

  if(Item<0 )
    Item=NodeCnt-1;
  else
    if(Item>=NodeCnt)
      Item=0;
  
  LVActive=Item;
  
  n=GetActiveNode();
  if(Keyed)
    LG_SetGadgetAttrs(GadControl,GD_LIST,
                    GTLV_Selected   ,LVActive,
                    TAG_DONE);
                    
  if(IMsg)
  {
    if(DoubleClick(SSecs,SMicros,IMsg->Seconds,IMsg->Micros) && DCNode==n)
    {
      SSecs=0;
      SMicros=0;
      if(n)
      {
        n->Flags^=DNF_NEVER_PROMOTE;
        fullupdate=1;
      }
    }
    else
    {
      SSecs  =IMsg->Seconds;
      SMicros=IMsg->Micros;
    }
    DCNode =n;
  }
  if(fullupdate)
  {
    UpdateGadgets();
  }
  else
  {
    LG_SetGadgetAttrs(GadControl,GD_MOVE,
                      GTSL_Max,       NodeCnt-1,
                      GTSL_Level,    (NodeCnt-1)-LVActive,
                      GA_Disabled,    FALSE,
                      TAG_DONE);
    SetDispGadgets(n);
    SetFontGadgets(n);
    SetSharedGadgets(n);
    SetPublicGadgets(n);
    SetHotKeyGadgets(n);
    SetOptionGadgets(n);
    Set3DGadgets(n);
    SetBackdropGadgets(n);
  }
    
  ActivateStrGad=GD_NAME;
}

void GD_SelectName(struct DefaultNode *N)
{
  LG_SetGadgetAttrs(GadControl,GD_LIST,
                           GTLV_Labels,~0,
                           TAG_DONE);
  SelectName(N);
  LG_SetGadgetAttrs(GadControl,GD_LIST,
                           GTLV_Labels,&MPSem->PromotionList[CurrentList],
                           TAG_DONE);
}

void GD_ModeSel(struct DefaultNode *N, LONG Mode, BOOL Keyed)
{
  LONG maxmode,minmode;
  
  if(Keyed)
  {
    // if keyed Mode is dirchange
    Mode+=N->ModeSelect;
  } 
  
  maxmode=MS_PROMOTE_MAX;//                                                                            (4.57.3)
  switch(N->Type)
  {
    case MPSEM_PLIST_PUBLICSCREENS:
      if(!Keyed)
        Mode+=2;
      minmode=2;
      break;
    default:
      minmode=0;
  }      
  
  if(Mode>maxmode)
    Mode=minmode;
  else
    if(Mode<minmode)
      Mode=maxmode;

  N->ModeSelect=Mode;
  SetDispGadgets(N);
}

void GD_SelMode(struct DefaultNode *N)
{
  switch(N->ModeSelect)
  {
    case MS_PROMOTE_MONITOR:
      SelectMonitor(N);
      break;
    case MS_PROMOTE_SCREENMODE:
    case MS_PROMOTE_REQUESTER:
      SelectScreenMode(Win,N,0);
      break;
    case MS_PROMOTE_BEST_MODE://                                                                       (4.57.14)
      SelectMonitor(N);//                                                                              (4.57.14)
      break;//                                                                                         (4.57.14)
  }
  SetDispGadgets(N);
  SetOptionGadgets(N);
}

/*
void GD_Overscan(struct DefaultNode *N, LONG Value, BOOL Keyed)
{
  if(Keyed)
  {
    Value+=N->OverscanType-DNODE_OSCANTYPE_MIN;
  }
  
  if(Value>DNODE_OSCANTYPE_MAX-DNODE_OSCANTYPE_MIN)
    Value=0;
  else
  {
    if(Value<0)
      Value=DNODE_OSCANTYPE_MAX-DNODE_OSCANTYPE_MIN;
  }

  N->OverscanType=Value+DNODE_OSCANTYPE_MIN;
  
  if(Keyed)
  {
    SetDispGadgets(N);
  }
}
*/

void GD_Overscan(struct DefaultNode *N, LONG Value, BOOL Keyed)
{
  if(Keyed)
  {
    Value+=N->OverscanType;
  }
  else
  {
    Value+=DNODE_OSCANTYPE_MIN;
  }
  
  if(Value>DNODE_OSCANTYPE_MAX)
    Value=DNODE_OSCANTYPE_MIN;

  if(Value<DNODE_OSCANTYPE_MIN)
    Value=DNODE_OSCANTYPE_MAX;

  N->OverscanType=Value;

  if(Keyed)
  {
    SetDispGadgets(N);
  }
}



void GD_Remove(struct DefaultNode *N)
{
  ObtainSemaphore(&MPSem->NodeSem);
  LG_SetGadgetAttrs(GadControl,GD_LIST,
                    GTLV_Labels,~0,TAG_DONE);
  if(!(N->Def_Node.ln_Succ->ln_Succ))
    if(LVActive>0)
      LVActive--;
  Remove((struct Node *)N);
  FreeDNode(N);
  ReleaseSemaphore(&MPSem->NodeSem);
  NodeCnt=CountNodes(&MPSem->PromotionList[CurrentList]); 
  UpdateGadgets();
}

void GD_PenList(struct DefaultNode *N, LONG Item,BOOL Keyed)
{
  if(Keyed)
  {
    Item+=ActivePen;
  }
  
  if(Item>=NumDriPens)
    Item=0;
  else
    if(Item<0)
      Item=NumDriPens-1;
  
  ActivePen=Item;
  if(N->Look3D)
  {
    ActivateStrGad=GD_PENVAL;
    SetPenValues(N->Pens);
  }
  else
    SetPenValues(0);
}


void GD_Interleave(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  SetDNFlag(N,INTERLEAVE,Set,Keyed);

  if(Keyed)
    SetOptionGadgets(N);
}

BOOL SetDNFlag(struct DefaultNode *N, ULONG Flag, BOOL Set, BOOL Keyed)
{
  if(Keyed)
  {
    Set=!(N->Flags & Flag);
  }
  
  N->Flags&=(~Flag);
  if(Set)
  {
    N->Flags|=Flag;
    return(1);
  }
  return(0);

}



void GD_Look3D(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  if(Keyed)
    N->Look3D=!N->Look3D;
  else
    N->Look3D=Set;
    
  Set3DGadgets(N);
}

void GD_AutoScroll(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  if(Keyed)
    N->AutoScroll=!N->AutoScroll;
  else
    N->AutoScroll=Set;
  
  if(Keyed) 
    SetOptionGadgets(N);
}
/*
void GD_PenVal(struct DefaultNode *N, BOOL Flag)
{
  N->Pens[ActivePen]=GetGadNumber(GadControl,GD_PENVAL]);
  if(imsg->Qualifier&3)
  {
    ActivePen--;
    if(ActivePen<0) ActivePen=NumDriPens-1;
  }
  else
  {
    ActivePen++;
    if(ActivePen>=NumDriPens) ActivePen=0;
  }
  ActivateStrGad=GD_PENVAL;
  SetPenValues(N->Pens);
}
*/
void GD_ResetPens(struct DefaultNode *N)
{
  LONG l;

  if(N->Look3D)
  {
    ObtainSemaphore(&MPSem->NodeSem);
    for(l=0;l<NumDriPens;l++)
      N->Pens[l]=defaultpens[l];
    ReleaseSemaphore(&MPSem->NodeSem);
    SetPenValues(N->Pens);
  }
}

void GD_PickFont(struct DefaultNode *N)
{
  if(PickFont(Win,&N->Font))
    SetFontGadgets(N);
}

void GD_Center(struct DefaultNode *N, LONG Num, BOOL Keyed)
{
  if(Keyed)
    Num+=N->CenterFlags;
  
  if(Num>MAX_CENTERFLAG)
    Num=0;

  if(Num<0)
    Num=MAX_CENTERFLAG;

  N->CenterFlags=Num;

  if(Keyed)
    SetOptionGadgets(N);
}

void GD_FAspect(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  SetDNFlag(N,FIXASPECT,Set,Keyed);
  
  if(Keyed)
    SetFontGadgets(N);
}

void GD_SFont(struct DefaultNode *N, LONG Code, BOOL Keyed)
{
  if(Keyed)
  {
    Code+=N->FontType;
  }
  
  if(Code>=MAX_FONT)
    Code=0;
  else
    if(Code<0)
      Code=MAX_FONT-1;
      
  N->FontType=Code;
  SetFontGadgets(N);
}

void GD_PubOpt(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  if(Keyed)
  {
    Set=!(N->PubOptions);
  }
  
  if(Set)
  {
    N->PubOptions=1;
    ActivateStrGad=GD_PUBNAME;
  }
  else
  {
    N->PubOptions=0;
  }

  SetPublicGadgets(N);
}
  
void GD_DoDepth(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{ 
  SetDNFlag(N,DEPTH,Set,Keyed);
  
  SetDepthGadgets(N);
}
  
void GD_SharePens(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  if(SetDNFlag(N,SHAREPENS,Set,Keyed))
  {
    ActivateStrGad=GD_LOCKEDPENS;
  }
  SetSharedGadgets(N);
}
  
void GD_HotKeyOpt(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  if(SetDNFlag(N,SCRHOTKEY,Set,Keyed))
  {
    ActivateStrGad=GD_HOTKEYSTR;
  }
  SetHotKeyGadgets(N);
}
  
void GD_Palette(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  SetDNFlag(N,DNF_PALETTE,Set,Keyed);
  SetPaletteGadgets(N);
}

void GD_EditPalette(struct DefaultNode *N)
{
  switch(N->ModeSelect)
  {
    case MS_PROMOTE_SCREENMODE:
    case MS_PROMOTE_REQUESTER:
    case MS_PROMOTE_BEST_MODE:
      if(N->Flags&DNF_PALETTE)
        PaletteReq(N);
      break;
  }
}

void GD_Move(LONG Num, BOOL Keyed)
{
  BOOL uplist=0;
  struct DefaultNode *n,*wn;

  if(Keyed)
  {
    Num+=LVActive;
  }

  if(Num>=NodeCnt)
    Num=0;
  else
    if(Num<0)
      Num=NodeCnt-1;
      
  
  if(NodeCnt)
  {
    ObtainSemaphore(&MPSem->NodeSem);
    n=GetActiveNode();
    Num=(NodeCnt-1)-Num;
    if(Num<LVActive) uplist=TRUE;
    LVActive=Num;
    if(wn=GetActiveNode())
      if(uplist) wn=(struct DefaultNode *)wn->Def_Node.ln_Pred;
        if(wn!=n)
        {
          LG_SetGadgetAttrs(GadControl,GD_LIST,
                   GTLV_Labels,~0,
                   TAG_DONE);
          Remove((struct Node *)n);
          Insert(&MPSem->PromotionList[CurrentList],(struct Node *)n,(struct Node *)wn);
          LG_SetGadgetAttrs(GadControl,GD_LIST,
                   GTLV_Labels,&MPSem->PromotionList[CurrentList],
                   GTLV_MakeVisible,LVActive,
                   GTLV_Selected,LVActive,TAG_DONE);
        }  
    ReleaseSemaphore(&MPSem->NodeSem); 
  }
}


void GD_Depth(struct DefaultNode *N, LONG Depth, BOOL Keyed)
{
  LONG maxdepth;
  
  if(Keyed)
    Depth+=N->Depth;
  
  if((N->ModeSelect==MS_PROMOTE_SCREENMODE || N->ModeSelect==MS_PROMOTE_REQUESTER || N->ModeSelect==MS_PROMOTE_BEST_MODE) && N->Flags & (DEPTH | DNF_PALETTE))//  (4.57.12)
  {
    if(Keyed)
    {
      struct DimensionInfo di;
    

      if(GetDisplayInfoData(NULL,(UBYTE *)&di,sizeof(di),DTAG_DIMS,N->ModeID)>0)
      {
        maxdepth=DepthToSlider[min(di.MaxDepth,32)];//                                                 (4.57.20)
        
        if(Depth>maxdepth)
          Depth=1;
        else
          if(Depth<1)
            Depth=maxdepth;
      }
      else
        Depth=1;
      
      LG_SetGadgetAttrs(GadControl,GD_DEPTH,
                      GTSL_Level      ,Depth,
                      TAG_DONE);
    }
    
    N->Depth=SliderToDepth[Depth];//                                                                   (4.57.21)
    WriteColorDisp(N);
  }
}

void GD_Force_Planar(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  SetDNFlag(N,DNF_FORCEPLANAR,Set,Keyed);
  
  if(Keyed)
    SetOptionGadgets(N);      
}

void GD_Blank_Border(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  SetDNFlag(N,DNF_BLANK_BORDER,Set,Keyed);
  
  if(Keyed) 
    SetOptionGadgets(N);
}

void GD_Behind(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  SetDNFlag(N,DNF_BEHIND,Set,Keyed);
  
  if(Keyed) 
    SetOptionGadgets(N);
}

void GD_3D_Default(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  SetDNFlag(N,DNF_3D_DEFAULT,Set,Keyed);

  Set3DGadgets(N);
}

void GD_BackdropOpt(struct DefaultNode *N, LONG Flag, BOOL Keyed)
{
  if(Keyed)
  {
    N->BackdropType+=Flag;
    if(N->BackdropType<0)
      N->BackdropType=DNODE_BACKDROPTYPE_MAX;
    if(N->BackdropType>DNODE_BACKDROPTYPE_MAX)
      N->BackdropType=0;
  }
  else
  {
    N->BackdropType=Flag;
  }
  
  if(N->BackdropType==DNODE_BACKDROPTYPE_IMAGE)
    N->BackdropFlags|=BF_ON; // compatibility for pre-4.47
    
  SetBackdropGadgets(N);
}

void GD_BackdropPick(struct DefaultNode *N)
{
  if(N)
  {
    if(SelectBackdropFile(GetString(MSG_BREQ_SELECT_BACKDROP),Win,N->BackdropFile))
    {
      FreeVec(N->BackdropFile);
      N->BackdropFile=CopyString(filename,MEMF_PUBLIC);
      SetBackdropGadgets(N);
    }
  }
}

ULONG my_DoRequest(Object *Obj, Tag Tags,...);

void GD_BackdropCenter(struct DefaultNode *N, BOOL Set, BOOL Keyed)
{
  if(Keyed)
  {
    Set=!(N->BackdropFlags & BF_CENTER);
  }
  
  N->BackdropFlags&=~BF_CENTER;
  if(Set)
    N->BackdropFlags|=BF_CENTER;
  
  if(Keyed)
    SetBackdropGadgets(N);      
}

/*
#include <boopsi/requesters/root.h>
#include <boopsi/requesters/palette.h>

void GD_BackdropColor(struct DefaultNode *N, BOOL Keyed)
{
  Object *BackdropPReq=0;
  
  if(!BackdropPReq)
  {
    LONG width;
    
    width=Win->Width/2;
    BackdropPReq=NewObject(0,"palette.requester",
                PR_Colors,          1,
                PR_TextAttr,        TAttr,
                PR_ObtainPens,      1,
                PR_InitialLeftEdge, Win->LeftEdge+width/2,
                PR_InitialTopEdge,  Win->TopEdge+8,
                PR_InitialWidth,    width,
                PR_InitialHeight,   Win->Height-16,
                TAG_DONE);
  }
  
  if(BackdropPReq)
  {
    if(my_DoRequest(BackdropPReq,
                      PR_Window,  Win,
                      PR_InitialPalette,  &N->BackdropRGB,
                      TAG_DONE))
    {
      struct RGB *p;
      
//      p=(struct RGB *)BackdropPReq->pr_Palette;
//      N->BackdropRGB=*p;      
      SetBackdropGadgets(N);
    }
    DisposeObject(BackdropPReq);
  }
}

ULONG my_DoRequest(Object *Obj, Tag Tags,...)
{
  return(DoMethod(Obj, RM_DOREQUEST, &Tags));
}
*/

#include <clib/extras/palettereq_protos.h>
#include <extras/palettereq.h>
extern  struct PaletteRequest *BackdropPReq;

void GD_BackdropColor(struct DefaultNode *N, BOOL Keyed)
{
  if(!BackdropPReq)
  {
    LONG width;
    
    width=Win->Width/2;
    BackdropPReq=PR_AllocPaletteRequest(
                PR_Colors,          1,
                PR_TextAttr,        TAttr,
                PR_ObtainPens,      1,
                PR_InitialLeftEdge, Win->LeftEdge+width/2,
                PR_InitialTopEdge,  Win->TopEdge+8,
                PR_InitialWidth,    width,
                PR_InitialHeight,   Win->Height-16,
                TAG_DONE);
  }
  
  if(BackdropPReq)
  {
    if(PR_DoPaletteRequest(BackdropPReq, 
                      PR_Window,  Win,
                      PR_InitialPalette,  &N->BackdropRGB,
                      TAG_DONE))
    {
      struct RGB *p;
      
      p=(struct RGB *)BackdropPReq->pr_Palette;
      N->BackdropRGB=*p;      
      SetBackdropGadgets(N);
    }
//    PR_FreePaletteRequest(BackdropPReq); // freed in CleanUp()
  }
}



void GD_FE_SaveUse(void)
{
  ReturnFEMsg(MPFE_SAVEUSE);
}

void GD_FE_UseDelete(void)
{
  ReturnFEMsg(MPFE_USEDELETE);
}

void GD_FE_Never(void)
{
  ReturnFEMsg(MPFE_NEVER);
}

void GD_FE_Cancel(void)
{
  ReturnFEMsg(MPFE_CANCEL);
}

void ReturnFEMsg(ULONG Code)
{
  if(ForcedEditMsg)
  {
    ForcedEditMsg->Code=Code;
    ReplyMsg((struct Message *)ForcedEditMsg);
  }
  
  if(!(ForcedEditMsg=(struct MPMessage *)GetMsg(&MPSem->PrefsToDoPort)))//                             (4.62.7)
  {
    RemakeGads();
  }
//  LVActive=0;
}

/*
void ReturnFEMsg(ULONG Code)
{
  struct MPMessage *mpm;
  
  if(mpm=(struct MPMessage *)RemHead(&ForcedEditList))
  {
    mpm->Code=Code;
    ReplyMsg((struct Message *)mpm);
  }
  if(IsListEmpty(&ForcedEditList))
    ForcedEditMode=0;
  
  RemakeGads();
}*/
