/******************************************************************************
 *
 * RCS ID
 * $Id: wimp,v 1.9 2002/11/17 16:43:22 david Exp $
 *
 * HISTORY
 * $Log: wimp,v $
 * Revision 1.9  2002/11/17 16:43:22  david
 * Updates to compiler with new 32-bit compiler
 *
 * Revision 1.8  2000/04/23 16:48:36  david
 * Changes to attempt fix for copying large files from Windows to
 * RISCOS problem. Fixes failed!
 *
 * Revision 1.7  2000/04/22 14:51:10  david
 * Updates for nmbd module debugging.
 * Updates for integrating nmbd with main smbserver application
 *
 * Revision 1.6  2000/04/17 16:48:53  david
 * Changed to wimpPollNonZero loop
 *
 * Revision 1.5  2000/04/02 16:59:14  david
 * Small tidy up!
 *
 * Revision 1.4  2000/02/08 20:18:16  david
 * Added help text for parameters.
 *
 * Revision 1.3  2000/01/29 17:24:47  david
 * Changed message and event handler registering to be driver by tables.
 *
 * Revision 1.2  2000/01/11 20:17:54  david
 * Added a define to split out booleans into General, File Create
 * and Filename read options. Not released yet - just playing with it.
 * Checked that !smbconfig will compile standalone.
 *
 * Revision 1.1  1999/11/07 15:15:20  david
 * New WIMP configuration using toolbox libs
 *
 *
 *
 *****************************************************************************/                    

 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>  
#include "kernel.h"
#include "swis.h"
#include "wimp.h"
#include "toolbox.h"
#include "event.h"
#include "dcs.h"
#include "wimplib.h"
#include "proginfo.h"
#include "quit.h"
#include "iconbar.h"   
#include "gadgets.h"
#include "menu.h"
#include "version.h"

#include "includes.h"
#include "smb.h"

#include "smbconfig.h"        

#include "smbswi.h"

#include "proto2.h"

#define WimpVersion    310
             

#define LEFT_BARICON  0
#define RIGHT_BARICON 1
#define NO_BARICON    2
            
#define FREEZE_MESSAGE  0x834d1
#define RESTORE_MESSAGE 0x834d0

extern int setSharePassword(ObjectId winId);

int bariconPos=LEFT_BARICON;



static  WimpPollBlock  poll_block;
static  MessagesFD     messages;
static  IdBlock        id_block;

int *pWimpPollWord=NULL; 
int *pEventType=NULL;
int *pSmbdSemaphore=NULL; 
int *pNmbdSemaphore=NULL;
int *pSmbdCbCount=NULL;

static int wimp_messages [] ={
        Wimp_MQuit,
        Wimp_MDataLoad,       
        Wimp_ERedrawWindow,
        Wimp_EUserDrag,
        Wimp_EMouseClick,  
        FREEZE_MESSAGE,
        RESTORE_MESSAGE,
        0};
                      


static int toolbox_events [] ={
        MyRedrawEvent,
        LargeIconsRequestEvent,
        SmallIconsRequestEvent,
        FullInfoRequestEvent,
        SelectAllEvent,
        ClearSelectionEvent,
        DeleteShareEvent,
        CloseShareEvent,
        DontCloseShareEvent,      
        ErrorBoxCloseEvent,    
        NmbdDebugEvent,
        Quit_Quit,
        Toolbox_ObjectAutoCreated,
        Window_AboutToBeShown,
        Menu_AboutToBeShown,
        ActionButton_Selected, 
        DCS_Discard,
        DCS_Save,
        0};

ObjectId MainWindowId=0; 
ObjectId ProgInfoId=0; 
ObjectId TopWindId=0;
ObjectId GlobWindId=0;
ObjectId SharesWindId=0;
ObjectId SharesMenuId=0;
ObjectId SharesMenu2Id=0;
ObjectId SharesMenu3Id=0;
ObjectId renameMenuId=0;
ObjectId copyMenuId=0;
ObjectId newShareMenuId=0;
ObjectId DCSId=0;
ObjectId closeShareWindId=0;
ObjectId errorBoxId=0;  
ObjectId setSharePasswordId=0;

tCreatedObjects createdObjects[] =
{
  { "TopWind",     &TopWindId,          genericObjectCreated },
  { "SharesWind",  &SharesWindId,       sharesWindCreated },
  { "GlobWind",    &GlobWindId,         genericObjectCreated },
  { "ProgInfo",    &ProgInfoId,         progInfoCreated },
  { "SharesMenu",  &SharesMenuId,       genericObjectCreated },
  { "SharesMenu2", &SharesMenu2Id,      genericObjectCreated },
  { "SharesMenu3", &SharesMenu3Id,      genericObjectCreated },
  { "Rename",      &renameMenuId,       genericObjectCreated },
  { "Copy",        &copyMenuId,         genericObjectCreated },
  { "NewShare",    &newShareMenuId,     genericObjectCreated },
  { "DCS",         &DCSId,              genericObjectCreated },
  { "CloseShare",  &closeShareWindId,   genericObjectCreated },  
  { "ErrorBox",    &errorBoxId,         errorBoxIdCreated },
  { "NewPassword", &setSharePasswordId, genericObjectCreated },  
  { NULL, 0, NULL}
};

tWimpHandlers wimpHandlers[] =
{
  {&TopWindId, Wimp_EMouseClick, topWindMouseClick},
  {&SharesWindId, Wimp_ERedrawWindow, redrawSharesWindow},
  {&SharesWindId, Wimp_EMouseClick, sharesWindMouseClick},
  { 0, 0, NULL}
};


tToolboxHandlers toolboxHandlers[] =
{                                    
  {&DCSId,            DCS_Discard,            discardConfigEvent},
  {&DCSId,            DCS_Save,               saveConfigEvent},
  {&SharesMenuId,     SelectAllEvent,         selectAllEvent},
  {&SharesMenuId,     ClearSelectionEvent,    sharesWindAboutToBeShown },
  {&SharesMenuId,     Menu_AboutToBeShown,    sharesMenuAboutToBeShown},
  {&SharesMenu2Id,    LargeIconsRequestEvent, sharesLargeEvent},
  {&SharesMenu2Id,    SmallIconsRequestEvent, sharesSmallEvent},
  {&SharesMenu2Id,    FullInfoRequestEvent,   sharesFullInfoEvent},
  {&SharesMenu3Id,    DeleteShareEvent,       deleteShareEvent},
  {&closeShareWindId, CloseShareEvent,        closeShareEvent},
  {&closeShareWindId, DontCloseShareEvent,    dontCloseShareEvent},
  {&GlobWindId,       Window_AboutToBeShown,  globWindAboutToBeShown},
  {&SharesWindId,     MyRedrawEvent,          sharesResizeEvent},
  {&SharesWindId,     Window_AboutToBeShown,  sharesWindAboutToBeShown}, 
  { 0, 0, NULL}
};

tpGadgetList GlobWindGadgets=NULL;
tpGadgetList SharesWindGadgets=NULL;

int lastWidth=0;
int frozen=False;

BOOL optionsChanged=False;
           
int nmbdDumpInfoEvent(int event_code,
                      ToolboxEvent *event,
                      IdBlock *id_block,
                      void *handle)
{                     
  nmbdDumpInfo();
  return 1;
}          

void showObjectInMiddle(ObjectId windId)
{
   int  coords[2];    
   BBox extent;

   window_get_extent(0, windId, &extent);
   get_screen_size(&coords[0],&coords[1]); 
   coords[0] = (coords[0]/2)-((extent.xmax-extent.xmin)/2);
   coords[1] = (coords[1]/2)+((extent.ymax-extent.ymin)/2);
   toolbox_show_object(0,windId,2,(void*)&coords[0],0,0);
}


int topWindOk(ObjectId winId)
{
   FILE *fp;

   fp = fopen(CONFIGFILE,"w"); 

   if (fp!=NULL)
      lp_dump(fp,False, lp_numservices()); 


   fclose(fp);

   window_set_title(0,TopWindId,"Samba Server Configuration");
   window_set_title(0,SharesWindId,"Shares");
   window_set_title(0,GlobWindId,"Global Variables");
     
   optionsChanged=False;

   return 1;
}

int actionButtonSelected(int event_code, 
                         ToolboxEvent *event, 
                         IdBlock *id_block,
                         void *handle)
{

  /* find which window it was */
  if ( (event->hdr.flags&0x08) ) /* default button */
  {

     if (id_block->self_id==TopWindId)
     {
        topWindOk(id_block->self_id);
     }  
     else
     if (id_block->self_id==GlobWindId)
     {
        globWindOk(id_block->self_id);
     }  
     else
     if (id_block->self_id==newShareMenuId)
     {
        addNewShare(id_block->self_id);
     }
     else
     if (id_block->self_id==renameMenuId)
     {
        renameShare(id_block->self_id);
     }   
     else                         
     if (id_block->self_id==copyMenuId)
     {
        copyShare(id_block->self_id);
     }
     else                         
     if (id_block->self_id==setSharePasswordId)
     {
        setSharePassword(id_block->self_id);
     }
     else
     {
        isSharesWindOk(id_block->self_id);
     }
  }
 
  return(1);
}


void create_and_show_icon_bar(char *appName)
{                                 
    ObjectId        IconBarId;
    ObjectId        IBarMenuId;
                                           
    if (strcmp(appName,"SmbServer")==0)
    {
       if (bariconPos==LEFT_BARICON)
          toolbox_create_object(0,"IconbarL",&IconBarId);
       else
       if (bariconPos==RIGHT_BARICON)
           toolbox_create_object(0,"IconbarR",&IconBarId);
                               
       if (bariconPos!=NO_BARICON)
       {
          toolbox_create_object(0,"IBarMenu",&IBarMenuId);
          iconbar_set_menu(0, IconBarId, IBarMenuId); 
          toolbox_show_object(0,IconBarId,0,0,0,0);

          event_register_toolbox_handler(IBarMenuId,
                                         NmbdDebugEvent,
                                         nmbdDumpInfoEvent,
                                         NULL);
       }
    }
    else
    if (strcmp(appName,"SmbConfig")==0)
    { 
       toolbox_create_object(0,"Iconbar",&IconBarId);
       toolbox_show_object(0,IconBarId,0,0,0,0);
    }
} 
                                             

                      
int aboutToExit(void)
{  
  ObjectId winId;

  if (optionsChanged==TRUE)
  {
    /* toolbox_show_object(0,DCSId,0,NULL,0,0);  */ 
    dcs_get_window_id(0,DCSId,&winId);
    showObjectInMiddle(winId);
  }
  else
  {
     exit(0);
  }

  return 1;

}

/*
 * Event handler to be called when toolbox event 1
 * is generated (by click on the 'Quit' entry of
 * the iconbar menu.
 */

int quit_event(int event_code, ToolboxEvent *event, IdBlock *id_block,void *handle)
{
  event_code = event_code;
  event = event;
  id_block = id_block;
  handle = handle;

  return(aboutToExit());
}





int dataLoadMessage(WimpMessage *message,void *handle)
{
  message = message;
  handle = handle;

  sharesDataLoadMessage(message);

  return(1);
}

/*
 * Message handler to be called on receipt of a
 * Quit or PreQuit message from the Wimp.
 */

int quit_message(WimpMessage *message,void *handle)
{
  message = message;
  handle = handle;

  return (aboutToExit());
}

int freeze_message(WimpMessage *message,void *handle)
{
  message = message;
  handle = handle;

  myexit();
  debug_log_close();
  frozen=True;      
           
  /* make sure the event is passed on */
  return 0;
}

int topWindMouseClick(int event_code, 
                      WimpPollBlock *event,
                      IdBlock *id_block,
                      void *v)
{

  if (event->mouse_click.buttons & Wimp_MouseButtonMenu) 
    return 1;

  if (id_block->self_component==0) /* smbserver button */
  {
    toolbox_show_object(0,GlobWindId,0,0,0,0);
  }

  if (id_block->self_component==1) /* shares button */
  {
    toolbox_show_object(0,SharesWindId,0,0,0,0);
  }

  return 1;

}
 


int progInfoCreated(ObjectId objId, ObjectId *pObjId, int index)
{
   ProgInfoId = objId;

   sprintf(versionString,"%s %s %s\n",ver_string,time_string,date_string);
   
   proginfo_set_version(0,ProgInfoId,versionString);
   return 1;
}

int discardConfigEvent(int event_code,
                       ToolboxEvent *event,
                       IdBlock *id_block,
                       void *handle)
{    
   exit(0);
   return 1;
}

int saveConfigEvent(int event_code,
                    ToolboxEvent *event,
                    IdBlock *id_block,
                    void *handle)
{    
   topWindOk(id_block->self_id);
   exit(0); 
   return 1;
}


int errorBoxIdCreated(ObjectId objId, ObjectId *pObjId, int index)
{
  /* errorBoxId = objId; */
  
   return 1;
}

int genericObjectCreated(ObjectId objId, ObjectId *pObjId, int index)
{              
   _kernel_oserror *e;   
   int i;

   *pObjId = objId; 

   i=0;
   while (wimpHandlers[i].objId!=0)
   {
 
     if (*wimpHandlers[i].objId == objId)
     {
       e=event_register_wimp_handler(*wimpHandlers[i].objId,
                                     wimpHandlers[i].eventCode,
                                     wimpHandlers[i].handler,
                                     NULL);
     }

     i++;
   }                     

   i=0;
   while (toolboxHandlers[i].objId!=0)
   {
 
     if (*toolboxHandlers[i].objId == objId)
     {
       e=event_register_toolbox_handler(*toolboxHandlers[i].objId,
                                        toolboxHandlers[i].eventCode,
                                        toolboxHandlers[i].handler,
                                        NULL);
     }

     i++;
   }           

   return 1;
}


int getCreatedObjectId(int event_code,
                       ToolboxEvent *event,
                       IdBlock *id_block,
                       void *handle)
{                
    int  i;       
    int  result=0;

    ToolboxObjectAutoCreatedEvent *tevent = 
        (ToolboxObjectAutoCreatedEvent *) event;

    IGNORE(handle);
    IGNORE(event_code);
     
    i=0;
    while (createdObjects[i].templateName!=NULL)
    {
       if ( (*createdObjects[i].objId==0) &&
            (strcmp(tevent->template_name,
                  createdObjects[i].templateName))==0)
       {
          result=createdObjects[i].createdObjFnc(id_block->self_id,
                                                 createdObjects[i].objId,
                                                 i);
       }                                                            
       i++;
    }

    return 1;
}
                         
int pollWordNonZero(int event_code, 
                    WimpPollBlock *event,
                    IdBlock *id_block,
                    void *v)
{        
  int tempLevel;            
  event_set_mask (256 |  Wimp_Poll_PollWord); 
#if 1
  DEBUG(1,("pollWord 0x%x, eventType %d, smbdSemaphore %d, nmbdSemaphore %d, smbdCbCount %d\n", 
        *pWimpPollWord, *pEventType, *pSmbdSemaphore, *pNmbdSemaphore, *pSmbdCbCount));
#endif
  while (*pEventType)
  {

    if ( (*pEventType) & SMBD_SOCKET_EVENT)
    {

      while (*pSmbdSemaphore)
      {  
#if 0
  DEBUG(0,("pollWord 0x%x, eventType %d, smbdSemaphore %d, nmbdSemaphore %d, smbdCbCount %d\n", 
        *pWimpPollWord, *pEventType, *pSmbdSemaphore, *pNmbdSemaphore, *pSmbdCbCount));
#endif
        resetPollWord(SMBD_SOCKET_EVENT);
        pollWordNonZeroAction();  
      }
    }    

    if ( (*pEventType) & NMBD_SOCKET_EVENT)
    {          
#if 0 
tempLevel=DEBUGLEVEL;
DEBUGLEVEL=10;
  DEBUG(1,("pollWord 0x%x, eventType %d, smbdSemaphore %d, nmbdSemaphore %d\n", 
        *pWimpPollWord, *pEventType, *pSmbdSemaphore, *pNmbdSemaphore));
#endif
      while (*pNmbdSemaphore)
      {
        resetPollWord(NMBD_SOCKET_EVENT);
        nmbdPollWordNonZeroAction(NMBD_SOCKET_EVENT);
      }    

#if 0
  DEBUG(1,("pollWord 0x%x, eventType %d, smbdSemaphore %d, nmbdSemaphore %d\n", 
        *pWimpPollWord, *pEventType, *pSmbdSemaphore, *pNmbdSemaphore));
DEBUGLEVEL=tempLevel;
#endif
    }                                    

    if ( (*pEventType) & NMBD_TIMEOUT_EVENT)
    {
      resetPollWord(NMBD_TIMEOUT_EVENT);     
      nmbdPollWordNonZeroAction(NMBD_TIMEOUT_EVENT);
    }                                 
  }

  DEBUG(1,("pollWord 0x%x, eventType %d, smbdSemaphore %d, nmbdSemaphore %d, smbdCbCount %d\n", 
        *pWimpPollWord, *pEventType, *pSmbdSemaphore, *pNmbdSemaphore, *pSmbdCbCount));

  event_set_mask (256 |  Wimp_Poll_PollWord | Wimp_Poll_NullMask);
  return 1;
}

int nullEvent(int event_code, 
              WimpPollBlock *event,
              IdBlock *id_block,
              void *v)
{          
/*                                                  
  if (doNullEvent()==0)
  { 
    event_set_mask (256 |  Wimp_Poll_PollWord | Wimp_Poll_NullMask);
  }
*/
  return 1;
}

static int event_code;

int WimpInitialise(char *appDir, char *appName)
{
    int result=1;
                     
    /* I'm sure there was an easier way to check this but I can't remember it! */
    if (taskCheck(appName)>0)
    {
        result=0;
       /* wimp_werr(0,"Only one copy of Samba can run at once."); */
    }
     
    {

        /*
         * register ourselves with the Toolbox.
         */

        toolbox_initialise (0, WimpVersion, wimp_messages, 
                            toolbox_events, appDir,
                            &messages, &id_block, 0, 0, 0);

        toolbox_create_object(0,"ErrorBox",&errorBoxId);
      /*  toolbox_show_object(0,errorBoxId,0,NULL,0,0); */
/*
         * initialise the event library.
         */

        event_initialise (&id_block);

        event_set_mask (256 |  Wimp_Poll_PollWord | Wimp_Poll_NullMask);

        /*
         * register handler for toolbox event 1,
         * which is generated by the 'Quit' option on the
         * iconbar menu.  Also register message handlers
         * to quit properly when quit messages are
         * received from the wimp.
         */

        event_register_toolbox_handler(-1,Quit_Quit,quit_event,0);
        event_register_toolbox_handler(-1,Toolbox_ObjectAutoCreated,
                                   getCreatedObjectId,NULL);
        event_register_toolbox_handler(-1,ActionButton_Selected,
                                   actionButtonSelected,NULL);
        event_register_message_handler(Wimp_MQuit,quit_message,0);
        event_register_message_handler(Wimp_MDataLoad,dataLoadMessage,0);
        event_register_message_handler(Wimp_MPreQuit,quit_message,0);
        event_register_message_handler(FREEZE_MESSAGE,freeze_message,0);

        event_register_wimp_handler(-1,Wimp_EPollWordNonZero,pollWordNonZero,0);
        event_register_wimp_handler(-1,Wimp_ENull,nullEvent,0);


        if (result==1) 
           create_and_show_icon_bar(appName);
    
        getPollWord();
        resetPollWord(SMBD_SOCKET_EVENT | NMBD_SOCKET_EVENT | NMBD_TIMEOUT_EVENT);
        resetFd();

    }

    return result;
}

void WimpPoll(void)
{
  event_poll (&event_code, &poll_block, pWimpPollWord);   
}
 
void wimp_werr(int severity,char *msg)
{
  /*werr (severity,msg);*/
  button_set_value(0,errorBoxId,0x1,msg);
  showObjectInMiddle(errorBoxId);
  VDU(7);
}

int getPollWord(void)
{
  _kernel_swi_regs r; 

  _kernel_swi(SmbServer_GetPollWord, &r, &r);  

  pWimpPollWord  = (int*)r.r[0]; 
  pEventType     = (int*)r.r[1];
  pSmbdSemaphore = (int*)r.r[2];
  pNmbdSemaphore = (int*)r.r[3];
  pSmbdCbCount   = (int*)r.r[4];

  DEBUG(0,("pWimpPollWord 0%.8x\n", pWimpPollWord));

  return 0;
}                       

int resetPollWord(int eventType)
{
  _kernel_swi_regs r; 
                               
  r.r[0] = eventType;
  _kernel_swi(SmbServer_ResetPollWord, &r, &r);  

  return 0;
}

int resetFd(void)
{
  _kernel_swi_regs r; 

  r.r[0] = SMBD_SOCK_SET;

  _kernel_swi(SmbServer_FdZero, &r, &r);  

  r.r[0] = NMBD_SOCK_SET;

  _kernel_swi(SmbServer_FdZero, &r, &r);  

  return 0;
}

                                                       
void wimpOnlyOneError(void)
{ 
   event_register_toolbox_handler(errorBoxId,ErrorBoxCloseEvent,quit_event,0);

   wimp_werr(0,"Only one copy of Samba can run at once.");
}

MessagesFD *getMsgFd(void)
{
  return &messages;
}     

char *getMsgFilename(void)
{
  return "<samba$dir>.Messages";
}

          
   



