/******************************************************************************
 *
 * RCS ID
 * $Id: shares,v 1.5 2002/11/17 16:43:22 david Exp $
 *
 * HISTORY
 * $Log: shares,v $
 * Revision 1.5  2002/11/17 16:43:22  david
 * Updates to compiler with new 32-bit compiler
 *
 * Revision 1.4  2000/02/20 16:41:20  david
 * Added calls to rename, copy and delete password file entries.
 *
 * Revision 1.3  2000/01/29 17:24:46  david
 * Changed message and event handler registering to be driver by tables.
 *
 * Revision 1.2  1999/11/23 22:04:02  david
 * Increased filename length to MAXPATHLEN
 *
 * 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 "wimplib.h"
#include "proginfo.h"
#include "quit.h"   
#include "gadgets.h"
#include "version.h"
#include "menu.h"

/*#include "RiscOSLib:werr.h"*/
#include "Risc_OSLib:werr.h"

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

#include "smbconfig.h"

extern BOOL deletePassFileEntry(char *entryName);
extern BOOL copyPassFileEntry(char *entryName, char *newEntryName);
extern BOOL renamePassFileEntry(char *entryName, char *newEntryName);

BOOL largeIcons=False;
BOOL fullInfo=False;

int scale,yscale;
BOOL dragging=False;
                                                           
char tmpPath[MAXPATHLEN];
BOOL tmpPathPresent=False;         

tpGadgetList addNewDirShare(char*);
               
void createOrDisplayChild(tpGadgetList aGadget)
{
   if (aGadget->childWindow==0)
   {
      toolbox_create_object(0,"ShareWind",&aGadget->childWindow);
      window_set_title(0,aGadget->childWindow,aGadget->label);
      addWindowGadgets(&aGadget->childGadgets,
                       aGadget->childWindow, 
                       aGadget->index.serviceIndex,
                       P_LOCAL);
   }                                       
   fillInGadgetFields(aGadget->childWindow,
                      aGadget->childGadgets,
                      aGadget->index.serviceIndex);                      
   toolbox_show_object(0,aGadget->childWindow,0,0,0,0);
}
          
void showInfoGadgets(ObjectId windowId, int scale, int yscale)
{
   tpGadgetList aGadget;
   int i=0,width=1;  
   
   aGadget =SharesWindGadgets;
   while (aGadget!=NULL)
   {       
      aGadget->infoGadgets->agadget.hdr.component_id = -1;
      aGadget->infoGadgets->agadget.hdr.box.xmin = scale+100;
      aGadget->infoGadgets->agadget.hdr.box.ymin = -yscale-((i/width)*yscale); 
      aGadget->infoGadgets->agadget.hdr.box.xmax = scale+750;
      aGadget->infoGadgets->agadget.hdr.box.ymax = -10-((i/width)*yscale);

      strcpy(aGadget->infoGadgets->label,
             lp_pathname(aGadget->index.serviceIndex)); 
 
      aGadget->infoGadgets->agadget.data.button.value=
          aGadget->infoGadgets->label;

      window_add_gadget(0,
                        windowId,
                        &aGadget->infoGadgets->agadget,
                        &aGadget->infoGadgets->agadget.hdr.component_id); 

      aGadget->infoGadgets->next->agadget.hdr.component_id = -1;
      aGadget->infoGadgets->next->agadget.hdr.box.xmin = scale+50;  
      aGadget->infoGadgets->next->agadget.hdr.box.ymin = -yscale-((i/width)*yscale); 
      aGadget->infoGadgets->next->agadget.hdr.box.xmax = scale+100;
      aGadget->infoGadgets->next->agadget.hdr.box.ymax = -10-((i/width)*yscale);

      if (lp_readonly(aGadget->index.serviceIndex)==True)
      {
         strcpy(aGadget->infoGadgets->next->label,"ro");
      }
      else
      {
         strcpy(aGadget->infoGadgets->next->label,"rw");
      }       
      aGadget->infoGadgets->next->agadget.data.button.value=
         aGadget->infoGadgets->next->label;

      window_add_gadget(0,
                        windowId,
                        &aGadget->infoGadgets->next->agadget,
                        &aGadget->infoGadgets->next->agadget.hdr.component_id); 
      aGadget=aGadget->next;  
      i++;
   }
}

void clearInfoGadgets(ObjectId windowId)
{
   tpGadgetList aGadget,bGadget;

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {                           
      
      bGadget=aGadget->infoGadgets;
      while (bGadget!=NULL)        
      {                                              
         window_remove_gadget(0,windowId,bGadget->agadget.hdr.component_id);     

         bGadget=bGadget->next;
      }

      aGadget=aGadget->next;
   }
}

int moveShareGadgets(ObjectId windowId,
                     int      width,
                     int      scale, 
                     int      yscale,
                     BOOL     createGadget)
{
   int bottom,i;
   tpGadgetList aGadget;  
   int ascale,x;      
 

   i=0;
   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {

      ascale=fontStrWidth(aGadget->label)+40;
                                                               
      if (largeIcons==True)
      {         
         x = ((scale+((i%width)*scale)) - (10+((i%width)*scale)))/2;
         x = x + 10+((i%width)*scale) - (ascale/2);
      }
      else
      {
         ascale += 20; 
         x = 10+((i%width)*scale); 
      }
          
      aGadget->agadget.hdr.box.xmin = x;
#if 0
      aGadget->agadget.hdr.box.xmin = 10+((i%width)*scale);
#endif

      aGadget->agadget.hdr.box.ymin = -yscale-((i/width)*yscale); 

#if 0
      aGadget->agadget.hdr.box.xmax = scale+((i%width)*scale);
#endif                                  
      aGadget->agadget.hdr.box.xmax = x+ascale; 

      aGadget->agadget.hdr.box.ymax = -10-((i/width)*yscale);
                                          
      if (createGadget==True)
      {
         window_add_gadget(0,
                           windowId,
                           &aGadget->agadget,
                           &aGadget->agadget.hdr.component_id);  
      }          
      else
      {
         gadget_move_gadget(0,
                            windowId,
                            aGadget->agadget.hdr.component_id,
                            &aGadget->agadget.hdr.box);
      }

      bottom = aGadget->agadget.hdr.box.ymin;
                             
      i++;
      aGadget=aGadget->next;
  }

  return bottom;
}
        
void createInfoGadget(tpGadgetList aGadget,
                      ObjectId windowId, 
                      int i, 
                      int width,
                      int yscale)
{                                    
   tpGadgetList bGadget;

      bGadget = (tpGadgetList) calloc (1, sizeof(tGadgetList));
      if (bGadget!=NULL)
      {
         bGadget->agadget.hdr.type   = Button_Base;
         bGadget->agadget.hdr.flags = 0x40000000;
         bGadget->agadget.hdr.box.xmin = 250;
         bGadget->agadget.hdr.box.ymin = -yscale-((i/width)*yscale); 
         bGadget->agadget.hdr.box.xmax = 1000;
         bGadget->agadget.hdr.box.ymax = -10-((i/width)*yscale);
         bGadget->agadget.hdr.component_id = -1;
         bGadget->agadget.hdr.help_message = help_message;
         bGadget->agadget.hdr.max_help     = sizeof(help_message)+1; 
         bGadget->agadget.data.button.button_flags=
             WimpIcon_Text | WimpIcon_Indirected | 
             WimpIcon_VCentred | (WimpIcon_ButtonType * ButtonType_DoubleClickDrag)
             | (WimpIcon_FGColour * 7) | (WimpIcon_BGColour * 1); 

         strcpy(bGadget->label,
             lp_pathname(aGadget->index.serviceIndex)); 
 
         bGadget->agadget.data.button.value=bGadget->label;
         bGadget->agadget.data.button.max_value=255;
         bGadget->agadget.data.button.validation=NULL;
         bGadget->agadget.data.button.max_validation =0;

         addGadget(&aGadget->infoGadgets,bGadget);


      }

      bGadget = (tpGadgetList) calloc (1, sizeof(tGadgetList));
      if (bGadget!=NULL)
      {
         bGadget->agadget.hdr.type   = Button_Base;
         bGadget->agadget.hdr.flags = 0;
         bGadget->agadget.hdr.box.xmin = 200;
         bGadget->agadget.hdr.box.ymin = -yscale-((i/width)*yscale); 
         bGadget->agadget.hdr.box.xmax = 250;
         bGadget->agadget.hdr.box.ymax = -10-((i/width)*yscale);
         bGadget->agadget.hdr.component_id = -1;
         bGadget->agadget.hdr.help_message = help_message;
         bGadget->agadget.hdr.max_help     = sizeof(help_message)+1; 
         bGadget->agadget.data.button.button_flags=
             WimpIcon_Text | WimpIcon_Indirected | 
             WimpIcon_VCentred  | (WimpIcon_ButtonType * ButtonType_DoubleClickDrag)
             | (WimpIcon_FGColour * 7) | (WimpIcon_BGColour * 1); 

         if (lp_readonly(aGadget->index.serviceIndex)==True)
         {
            strcpy(bGadget->label,"ro");
         }
         else
         {
            strcpy(bGadget->label,"rw");
         }               

 
 
         bGadget->agadget.data.button.value=bGadget->label;
         bGadget->agadget.data.button.max_value=255;
         bGadget->agadget.data.button.validation=NULL;
         bGadget->agadget.data.button.max_validation =0;

         addGadget(&aGadget->infoGadgets,bGadget);


      }
}
                            
void createInfoGadgets(ObjectId windowId, int compId)
{
   tpGadgetList aGadget; 
   int i=0,width=1;  
   int yscale=60;                     

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {
                     
      createInfoGadget(aGadget,windowId,i,width,yscale);
                                                               
      i++;
      aGadget=aGadget->next;
   }
}

tpGadgetList createShareGadget(ObjectId windowId, int i, int width)
{                                                         
   tpGadgetList aGadget;

      aGadget = (tpGadgetList) calloc (1, sizeof(tGadgetList));

      if (aGadget!=NULL)
      {
         aGadget->index.serviceIndex=i;
         aGadget->agadget.hdr.flags = 0;
         aGadget->agadget.hdr.type   = 960;
         aGadget->agadget.hdr.box.xmin = 10+((i%width)*scale);
         aGadget->agadget.hdr.box.ymin = -yscale-((i/width)*yscale); 
         aGadget->agadget.hdr.box.xmax = scale+((i%width)*scale);
         aGadget->agadget.hdr.box.ymax = -10-((i/width)*yscale);
         aGadget->agadget.hdr.component_id = -1;
         aGadget->agadget.hdr.help_message = help_message;
         aGadget->agadget.hdr.max_help     = sizeof(help_message);
         aGadget->agadget.data.button.button_flags=
             WimpIcon_Text | WimpIcon_Sprite | WimpIcon_Indirected | WimpIcon_HCentred |
             /* WimpIcon_Border | */ (WimpIcon_ButtonType * ButtonType_DoubleClickDrag)
                           | (WimpIcon_FGColour * 7) | (WimpIcon_BGColour * 1)
                           ; 
         strcpy(aGadget->label,lp_servicename(i));
         aGadget->agadget.data.button.value=aGadget->label;
         aGadget->agadget.data.button.max_value=255;

         if (lp_print_ok(i)==True)
         {
            aGadget->agadget.data.button.validation=Sprinters;
            aGadget->agadget.data.button.max_validation=strlen(Sprinters)+10;
         }
         else
         {
            aGadget->agadget.data.button.validation=Sharddisc;
            aGadget->agadget.data.button.max_validation=strlen(Sharddisc)+10;
         }

         window_add_gadget(0,
                           windowId,
                           &aGadget->agadget,
                           &aGadget->agadget.hdr.component_id);  


         addGadget(&SharesWindGadgets,aGadget); 
    } 

   return aGadget;
}

int createShareGadgets(ObjectId windowId)
{
                            
   int i,width,ascale;
   tpGadgetList aGadget;  
   WimpGetWindowStateBlock state;
   BBox extent;              

   largeIcons = True;
   fullInfo   = False;

   scale  = 150; 
   yscale = 130;
 
   window_get_wimp_handle(0,windowId,&state.window_handle);
   wimp_get_window_state(&state);                                         
             
   width = (state.visible_area.xmax-state.visible_area.xmin)/scale;
   if (width<=0)
     width=1; 
   lastWidth=width;

   for (i=0; i< lp_numservices(); i++)
   {                 
      if (lp_valid(i))                          
      {
         ascale=fontStrWidth(lp_servicename(i))+40; 
         if (ascale>scale)
           scale=ascale;
      }
         
   } /* for */

   for (i=0; i< lp_numservices(); i++)
   {                 
      if (lp_valid(i) && strcmp(lp_servicename(i),"IPC$")!=0)                          
         aGadget=createShareGadget(windowId,i,width);
        
   } /* for */

   sortGadgetList(&SharesWindGadgets,
                  offsetof(tGadgetList,label),
                  QSORT_CAST StrCaseCmp);
                                        

   createInfoGadgets(windowId,i);

   window_get_extent(0,windowId,&extent);
   extent.ymin=moveShareGadgets(windowId,lastWidth,scale,yscale,False)-20;
   window_set_extent(0,windowId,&extent);  

   return 0;
}          

int sharesChangeEvent(ObjectId windId,
                      int      *scale, 
                      int      yscale,
                      char     *printersSprite,
                      char     *discsSprite,
                      int      flags,
                      int      lastWidth) 
{
   _kernel_oserror *e;
   tpGadgetList aGadget;  
   BBox extent,extent2;
   int  ascale=0;
        
   *scale=0;

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {                     

      ascale=fontStrWidth(aGadget->label)+40+((largeIcons==True)?0:30);
      if (ascale>*scale)
         *scale=ascale;

      button_set_flags(0,
                       windId,
                       aGadget->agadget.hdr.component_id,
                       (WimpIcon_HCentred|WimpIcon_VCentred),
                       flags);        

      if (lp_print_ok(aGadget->index.serviceIndex)==True)
      {   
         e=button_set_validation(0,
                                 windId,
                                 aGadget->agadget.hdr.component_id,
                                 printersSprite);                                             
      }
      else
      {
         e=button_set_validation(0,
                                 windId,
                                 aGadget->agadget.hdr.component_id,
                                 discsSprite);
      }           
      if (e!=NULL)
      {    
         DEBUG(2,("oserr %s, %d\n",e->errmess,e->errnum));
      }
      aGadget=aGadget->next;
   }
   
   window_get_extent(0,windId,&extent); 
   extent2=extent;
   extent.ymin=moveShareGadgets(windId,lastWidth,*scale,yscale,False)-20;
   window_set_extent(0,windId,&extent);  
                  
   window_force_redraw(0,windId,&extent2);
   toolbox_hide_object(0,windId);
   toolbox_show_object(0,windId,0,0,0,0);  
           
   return 1;
}  

int sharesLargeEvent(int event_code,
                     ToolboxEvent *event,
                     IdBlock *id_block,
                     void *handle)
{
   scale = 150;                              
   yscale = 130;

   if (fullInfo==True)
   {
      clearInfoGadgets(SharesWindId);
   }
     
   largeIcons=True;
   fullInfo=False;  

               

   return sharesChangeEvent(SharesWindId,
                            &scale,
                            yscale,
                            Sprinters,
                            Sharddisc,
                            WimpIcon_HCentred,
                            lastWidth);
}  

int sharesSmallEvent(int event_code,
                     ToolboxEvent *event,
                     IdBlock *id_block,
                     void *handle)
{
   scale = 200; 
   yscale = 60;                           

   if (fullInfo==True)
   {
      clearInfoGadgets(SharesWindId);
   }

   largeIcons=False;
   fullInfo=False;
     
   return sharesChangeEvent(SharesWindId,
                            &scale,
                            yscale,
                            Ssmprinters,
                            Ssmharddisc,
                            WimpIcon_VCentred,
                            lastWidth);
}  

int sharesFullInfoEvent(int event_code,
                        ToolboxEvent *event,
                        IdBlock *id_block,
                        void *handle)
{
   BOOL showInfoG=False;
   scale = 200; 
   yscale = 60;

   if (fullInfo==False)
   {                    
      showInfoG=True;
   }                            

   largeIcons=False;
   fullInfo=True;
     
   sharesChangeEvent(SharesWindId,
                            &scale,
                            yscale,
                            Ssmprinters,
                            Ssmharddisc,
                            WimpIcon_VCentred,
                            1);
                     
   if (showInfoG==True)
   {
      showInfoGadgets(SharesWindId,scale,yscale);
   }

   return 1;
}  

int sharesResizeEvent(int event_code,
                      ToolboxEvent *event,
                      IdBlock *id_block,
                      void *handle)
{  
   BBox extent;                                   
 
   if (fullInfo==False)
   {
      window_get_extent(0,id_block->self_id,&extent);
      extent.ymin=moveShareGadgets(id_block->self_id,lastWidth,scale,yscale,False)-20;
      window_set_extent(0,id_block->self_id,&extent);
      window_force_redraw(0,id_block->self_id,&extent);  
   }

   return 1; 
}
          
int redrawNow(void)
{
      if (largeIcons==True)                                   
      {
        
        sharesLargeEvent(0,NULL,NULL,NULL);
      }
      else
      {
         if (fullInfo==True)
         {
           
            sharesFullInfoEvent(0,NULL,NULL,NULL);
         }
         else 
         {
            
            sharesSmallEvent(0,NULL,NULL,NULL);
         }     
      }  

   return 1;
}

BOOL overInfoGadget(tpGadgetList aGadget,BBox *eventBbox)
{     
   BOOL result=False;
   tpGadgetList bGadget;
           
   if (fullInfo==True)
   {
      bGadget=aGadget->infoGadgets;
      while (bGadget!=NULL)
      {

         if (boxexOverlap(eventBbox,
                          &bGadget->agadget.hdr.box )==True)
         {
            result=True;
            break;
         }

         bGadget=bGadget->next;
      }       
   }

   return result;
}
                                                          
BOOL isInList(tpGadgetList aGadget, int compId)
{     
   BOOL result=False;
   tpGadgetList bGadget;
                 
   if (fullInfo==True)
   {
      bGadget=aGadget;
      while (bGadget!=NULL)
      {
                     
         if (bGadget->agadget.hdr.component_id == compId)
         {
            result=True;
            break;
         }

         bGadget=bGadget->next;
      }       
   }

   return result;
}


int redrawSharesWindow(int           event_code, 
                       WimpPollBlock *event,
                       IdBlock       *id_block,
                       void *v)
{
   int more;
   WimpGetWindowStateBlock state;
   WimpRedrawWindowBlock block;
   BBox extent;
   int width;
   ToolboxEvent newevent;

   IGNORE(id_block);
   IGNORE(event_code);

   state.window_handle = event->redraw_window_request.window_handle;
   block.window_handle = event->redraw_window_request.window_handle;

   window_get_extent(0,id_block->self_id,&extent);

   wimp_get_window_state(&state);                                         
             
   width = (state.visible_area.xmax-state.visible_area.xmin)/scale;
   if (width<=0)
     width=1;

   if ( width != lastWidth)
   {
      lastWidth=width;
      newevent.hdr.size=16;
      newevent.hdr.reference_number=0x1234;
      newevent.hdr.event_code = MyRedrawEvent;
      newevent.hdr.flags=0;
      toolbox_raise_toolbox_event(0,id_block->self_id,-1,&newevent);
   }

   wimp_redraw_window(&block,&more);
   while (more)
   {                  
      wimp_get_rectangle (&block,&more);
   }

   /* claimed */

   return 1;
}

int sharesWindUserDrag(int event_code, 
                       WimpPollBlock *event,
                       IdBlock *id_block,
                       void *v)
{
   int          flags;
   tpGadgetList aGadget; 
   WimpGetWindowStateBlock state; 

   window_get_wimp_handle(0,SharesWindId,&state.window_handle);
        
   wimp_get_window_state(&state);

   screenToWorkCoords(&event->user_drag_box.bbox,&state);
      
#if 0
   DEBUG(2,("user drag (%d,%d) (%d,%d)\n",
           event->user_drag_box.bbox.xmin, event->user_drag_box.bbox.ymin,
           event->user_drag_box.bbox.xmax, event->user_drag_box.bbox.ymax)); 
#endif

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {
            
      DEBUG(2,("gadget %s\n",aGadget->label));

      if (boxexOverlap(&event->user_drag_box.bbox,
                       &aGadget->agadget.hdr.box )==True ||
          overInfoGadget(aGadget,&event->user_drag_box.bbox)==True)
      {
            button_set_flags(0,
                             SharesWindId,
                             aGadget->agadget.hdr.component_id,
                             WimpIcon_Selected,
                             WimpIcon_Selected);
      }
      else
      {
            button_get_flags(0,
                             SharesWindId,
                             aGadget->agadget.hdr.component_id,
                             &flags);

            if (flags & WimpIcon_Selected)
            { 
               button_set_flags(0,
                                SharesWindId,
                                aGadget->agadget.hdr.component_id,
                                WimpIcon_Selected,
                                0);
            }
      }
    
      aGadget=aGadget->next;
   }                        

   return 1;
}

int sharesWindMouseClick(int event_code, 
                         WimpPollBlock *event,
                         IdBlock *id_block,
                         void *v)
{
   tpGadgetList aGadget;  
   int          flags;

#if 0
   DEBUG(2,("shares mouse click event: x %d, y %d, buttons 0x%x, wh 0x%x, icon 0x%x\n",
           event->mouse_click.mouse_x, event->mouse_click.mouse_y,
           event->mouse_click.buttons, event->mouse_click.window_handle,
           event->mouse_click.icon_handle));                             
   DEBUG(2,("button %d\n",id_block->self_component));
#endif

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {                   
      /* double click */
      if (event->mouse_click.buttons & Wimp_MouseButtonSelect)
      {
         /* select the selected button only */                
         if (id_block->self_component == aGadget->agadget.hdr.component_id ||
             isInList(aGadget->infoGadgets,id_block->self_component))
         {

            button_set_flags(0,
                             SharesWindId,
                             aGadget->agadget.hdr.component_id,
                             WimpIcon_Selected,
                             0);
            createOrDisplayChild(aGadget);
         }

      }

      /* single click - if select pressed */
      if (event->mouse_click.buttons & (Wimp_MouseButtonSelect*256))
      {
         /* select the selected button only */                
         if (id_block->self_component == aGadget->agadget.hdr.component_id  ||
             isInList(aGadget->infoGadgets,id_block->self_component))
         {

            button_set_flags(0,
                             SharesWindId,
                             aGadget->agadget.hdr.component_id,
                             WimpIcon_Selected,
                             WimpIcon_Selected);
         }
         else /* clear the rest */
         {
 
            button_get_flags(0,
                             SharesWindId,
                             aGadget->agadget.hdr.component_id,
                             &flags);

            if (flags & WimpIcon_Selected)
            { 
               button_set_flags(0,
                                SharesWindId,
                                aGadget->agadget.hdr.component_id,
                                WimpIcon_Selected,
                                0);
            }
         }
      }

      /* if adjust pressed toggle button */
      if (event->mouse_click.buttons & (Wimp_MouseButtonAdjust*256))
      {
         /* select the selected button only */                
         if (id_block->self_component == aGadget->agadget.hdr.component_id  ||
             isInList(aGadget->infoGadgets,id_block->self_component))
         {
            button_get_flags(0,
                             SharesWindId,
                             aGadget->agadget.hdr.component_id,
                             &flags);

            if (flags & WimpIcon_Selected)
            { 
               button_set_flags(0,
                                SharesWindId,
                                aGadget->agadget.hdr.component_id,
                                WimpIcon_Selected,
                                0);
            }
            else
            {
               button_set_flags(0,
                                SharesWindId,
                                aGadget->agadget.hdr.component_id,
                                WimpIcon_Selected,
                                WimpIcon_Selected); 
            }
         }
      }
      


      /* drag click - if select pressed */
      if (event->mouse_click.buttons & (Wimp_MouseButtonSelect*16))
      {
         WimpDragBox dragBox;
         WimpGetWindowStateBlock state;

         window_get_wimp_handle(0,SharesWindId,&dragBox.wimp_window);
         state.window_handle=dragBox.wimp_window;
         wimp_get_window_state(&state);
         dragBox.drag_type = Wimp_DragBox_DragRubberDash;
         dragBox.dragging_box.xmin = event->mouse_click.mouse_x;
         dragBox.dragging_box.ymin = event->mouse_click.mouse_y;
         dragBox.dragging_box.xmax = event->mouse_click.mouse_x;
         dragBox.dragging_box.ymax = event->mouse_click.mouse_y;  
         dragBox.parent_box.xmin   = state.visible_area.xmin;
         dragBox.parent_box.ymin   = state.visible_area.ymin;
         dragBox.parent_box.xmax   = state.visible_area.xmax;
         dragBox.parent_box.ymax   = state.visible_area.ymax; 
         dragBox.workspace         = 0;
         dragBox.draw              = NULL;
         dragBox.remove            = NULL;
         dragBox.move              = NULL;   

         dragging=True;              

         wimp_drag_box(&dragBox);
      }

      aGadget=aGadget->next;
   }

   return 1;

}

int sharesWindAboutToBeShown(int event_code,
                             ToolboxEvent *event,
                             IdBlock *id_block,
                             void *handle)
{  
   tpGadgetList aGadget; 

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   { 
      button_set_flags(0,
                       SharesWindId,
                       aGadget->agadget.hdr.component_id,
                       WimpIcon_Selected,
                       0);
      aGadget=aGadget->next;
   }

   return 1;
}
                                   
int getSelectedGadget(tpGadgetList *selectedGadget)
{
   tpGadgetList aGadget; 
   int selected=0;
   int flags;

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   { 
      button_get_flags(0,
                       SharesWindId,
                       aGadget->agadget.hdr.component_id,
                       &flags);

      if (flags & WimpIcon_Selected)
      {                               
         *selectedGadget=aGadget;
         selected++;
      }     

      aGadget=aGadget->next;
   }

   return selected;
}

int sharesMenuAboutToBeShown(int event_code,
                             ToolboxEvent *event,
                             IdBlock *id_block,
                             void *handle)
{  
   tpGadgetList selectedGadget; 
   int selected=0;
   char menuText[99];                   

   selected = getSelectedGadget(&selectedGadget);
                             
   tmpPathPresent=False;

   if (selected==0)
   {
      sprintf(menuText,"Share ''");
      menu_set_fade(0,SharesMenuId,0x1,1);
   }
   else
   if (selected==1)
   {
      sprintf(menuText,"Share '%s'",selectedGadget->label);
      menu_set_fade(0,SharesMenuId,0x1,0);
      menu_set_fade(0,SharesMenu3Id,0x0,0);
      menu_set_fade(0,SharesMenu3Id,0x1,0);
      menu_set_fade(0,SharesMenu3Id,0x3,0);
      writablefield_set_value(0,renameMenuId,0,selectedGadget->label);
      writablefield_set_value(0,copyMenuId,0,selectedGadget->label);    
      writablefield_set_value(0,setSharePasswordId,0,NULL);  
   }
   else
   {
      strcpy(menuText,"Selection");    
      menu_set_fade(0,SharesMenuId,0x1,0);
      menu_set_fade(0,SharesMenu3Id,0x0,1);
      menu_set_fade(0,SharesMenu3Id,0x1,1);
      menu_set_fade(0,SharesMenu3Id,0x3,1);
   }
                                   
   menu_set_entry_text(0,SharesMenuId,0x1,menuText);

   return 1;
}            

int sharesWindCreated(ObjectId objId, ObjectId *pObjId, int index )
{
   _kernel_oserror *e;
   SharesWindId = objId;

   createShareGadgets(SharesWindId);  
    
   e=event_register_wimp_handler(-1,
                               Wimp_EUserDrag,
                               sharesWindUserDrag,
                               NULL);  

   genericObjectCreated(objId, pObjId, index);

#if 0 
  e=event_register_wimp_handler(SharesWindId,
                               Wimp_ERedrawWindow,
                               redrawSharesWindow,
                               NULL);
   e=event_register_wimp_handler(SharesWindId,
                               Wimp_EMouseClick,
                               sharesWindMouseClick,
                               NULL);

   e=event_register_toolbox_handler(SharesWindId,
                                  MyRedrawEvent,
                                  sharesResizeEvent,
                                  0);
   e=event_register_toolbox_handler(SharesWindId,
                                  Window_AboutToBeShown,
                                  sharesWindAboutToBeShown,
                                  NULL);    
#endif

   return 1;
}

int selectAllEvent(int event_code,
                   ToolboxEvent *event,
                   IdBlock *id_block,
                   void *handle)
{ 
   tpGadgetList aGadget; 

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   { 
      button_set_flags(0,
                       SharesWindId,
                       aGadget->agadget.hdr.component_id,
                       WimpIcon_Selected,
                       WimpIcon_Selected);
      aGadget=aGadget->next;
   }

   return 1;
}


 


BOOL anySelectedSharesInUse(void)
{
   BOOL result=False;
   tpGadgetList aGadget;
   int flags;
   char errString[50];


   aGadget=SharesWindGadgets;
   while (aGadget!=NULL && result==False)
   {

      button_get_flags(0,
                       SharesWindId,
                       aGadget->agadget.hdr.component_id,
                       &flags);

      if (flags & WimpIcon_Selected)
      {               
         if (conn_snum_used(aGadget->index.serviceIndex)==True)
         {
            sprintf(errString,"Share %s is in use.",
                    lp_servicename(aGadget->index.serviceIndex));
            /*wimp_werr(0,errString);*/
            button_set_value(0,closeShareWindId,0,errString);
            button_set_value(0,closeShareWindId,4,
                             "Close connections and delete?"); 
            showObjectInMiddle(closeShareWindId);
            VDU(7);
            result=True;
         }                  
        
      }
      aGadget=aGadget->next;
   }

   return result;
}
                    
int deleteShareEvent(int event_code,
                     ToolboxEvent *event,
                     IdBlock *id_block,
                     void *handle)
{            
   tpGadgetList aGadget,bGadget,next,bnext; 
   int flags;
   BOOL deletedGadget=False;
     
   if (anySelectedSharesInUse()==True)
   {                        
      /* 
       * wait for connections to be closed or for selected shares
       * to be unselected before continuing with delete.
       */
      return 1;
   }

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   { 
      next=aGadget->next;

      button_get_flags(0,
                       SharesWindId,
                       aGadget->agadget.hdr.component_id,
                       &flags);

      if (flags & WimpIcon_Selected)
      {            
         
         bGadget=aGadget->infoGadgets;
         while (bGadget!=NULL)
         {                                
            bnext=bGadget->next;
            if (fullInfo==True)
            {
               window_remove_gadget(0,
                                    SharesWindId,
                                    bGadget->agadget.hdr.component_id);  
            }                                       
                                     
            deleteGadget(&aGadget->infoGadgets,bGadget);
            free(bGadget);
            bGadget=bnext;
         }                            
                                
         deletePassFileEntry(lp_servicename(aGadget->index.serviceIndex));
         lp_remove_service(aGadget->index.serviceIndex);

         window_remove_gadget(0,
                              SharesWindId,
                              aGadget->agadget.hdr.component_id);                             
         deleteGadget(&SharesWindGadgets,aGadget);  

         deletedGadget=True;
         free(aGadget); 
         
      }     
            
     
      aGadget=next;
   }
                          
   if (deletedGadget==True) 
   {
      window_set_title(0,TopWindId,"Samba Server Configuration *");
      window_set_title(0,SharesWindId,"Shares *");   
      optionsChanged=True;
   }

   redrawNow();

   return 1;
}    

void clearOrFreeFirstSelectedShare(BOOL deleteShare)
{
   BOOL result=False;
   tpGadgetList aGadget;
   int flags;

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL && result==False)
   {

      button_get_flags(0,
                       SharesWindId,
                       aGadget->agadget.hdr.component_id,
                       &flags);

      if (flags & WimpIcon_Selected)
      {               
         if (conn_snum_used(aGadget->index.serviceIndex)==True)
         {
            if (deleteShare==True)
            {
               conn_close_service(aGadget->index.serviceIndex);  
            }
            else
            {                      
               /* clear flag - not going to delete it */
               button_set_flags(0,
                                SharesWindId,
                                aGadget->agadget.hdr.component_id,
                                WimpIcon_Selected,
                                0);
            }
            
            result=True;
         }                  
        
      }
      aGadget=aGadget->next;
   }
   
   /* not delete shares */
   deleteShareEvent(0,NULL,NULL,NULL);
}


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

  clearOrFreeFirstSelectedShare(True);

  return 1;
}

int dontCloseShareEvent(int event_code,
                        ToolboxEvent *event,
                        IdBlock *id_block,
                        void *handle)
{ 
  clearOrFreeFirstSelectedShare(False);
 
  return 1;
}



int sharesDataLoadMessage(WimpMessage *message)
{
   int          winId;
   tpGadgetList aGadget,bGadget; 
   int          result=0;                       
   int          iconListBuffer[10];      
   int          nBytes;
   int          i=0,ftype;
   char         *c, leafName[MAXPATHLEN];
            
   if (message->data.data_load.file_type==0x1000 ||
       message->data.data_load.file_type==0x2000 ||
       objectType(message->data.data_load.leaf_name,&ftype)>=2)
   {
      
   window_get_wimp_handle(0,SharesWindId,&winId); 

   if (message->data.data_load.destination_window == winId)
   {
    
      c=strrchr(message->data.data_load.leaf_name,'.');
      strcpy(leafName,c+1); 
      aGadget=addNewDirShare(leafName); 

      if (aGadget!=NULL)
      {    
         lp_set_path(aGadget->index.serviceIndex,message->data.data_load.leaf_name);
      }                
      else
      {
         strcpy(tmpPath,message->data.data_load.leaf_name);
         tmpPathPresent=True;
      }
   }
   else
   {         
   /* search windows */
   aGadget=SharesWindGadgets;
   while (aGadget!=NULL && result==0)
   { 
                      
      window_get_wimp_handle(0,aGadget->childWindow,&winId);
                       
      /* found window */
      if (message->data.data_load.destination_window == winId)
      {                 
        
         /* search gadgets */
         bGadget=aGadget->childGadgets;
         while (bGadget!=NULL && result==0)
         {                        
            /* search icons that make up gadget */
            gadget_get_icon_list(0,
                                 aGadget->childWindow,
                                 bGadget->agadget.hdr.component_id,
                                 iconListBuffer,
                                 sizeof(iconListBuffer),
                                 &nBytes);  
            for (i=0;i<nBytes && result==0;i++)
            {
               if (iconListBuffer[i]==message->data.data_load.destination_icon &&
                   strcmp(lpGetParamStruct(bGadget->index.paramIndex)->label,"path")==0)
               {
                  /* this is it! */

                  if (bGadget->agadget.hdr.type == WritableField_Base)
                  {
       

                        strncpy(bGadget->agadget.data.writable_field.text,
                                message->data.data_load.leaf_name,
                                255);
                        writablefield_set_value(0,
                                                aGadget->childWindow,
                                                bGadget->agadget.hdr.component_id,
                                                bGadget->agadget.data.writable_field.text);
              
                  } 

                  result=1;
               }
            }
            bGadget=bGadget->next;
         }
      }

      aGadget=aGadget->next;
   }
   }
   }
   else
   {
         /*bbc_vdu(7);*/
      VDU(7);
      wimp_werr(0,"Path must be a directory or image file.");
    }      

   return result; 

}                                    

int updateSharesWindow(tpGadgetList aGadget)
{
   if (lp_readonly(aGadget->index.serviceIndex)==True)
   {
      strcpy(aGadget->infoGadgets->next->label,"ro");
   }
   else
   {
      strcpy(aGadget->infoGadgets->next->label,"rw");
   }       
   aGadget->infoGadgets->next->agadget.data.button.value=
      aGadget->infoGadgets->next->label;

   strcpy(aGadget->infoGadgets->label,
          lp_pathname(aGadget->index.serviceIndex)); 
 
   aGadget->infoGadgets->agadget.data.button.value=
      aGadget->infoGadgets->label;

   if (largeIcons==True)
   {
      if (lp_print_ok(aGadget->index.serviceIndex)==True)
      {
         aGadget->agadget.data.button.validation=Sprinters;         
      }
      else
      {
         aGadget->agadget.data.button.validation=Sharddisc;         
      }                                             
   }
   else
   {
      if (lp_print_ok(aGadget->index.serviceIndex)==True)
      {
         aGadget->agadget.data.button.validation=Ssmprinters;         
      }
      else
      {
         aGadget->agadget.data.button.validation=Ssmharddisc;         
      }

      if (fullInfo)
      {
         button_set_value(0,
                          SharesWindId, 
                          aGadget->infoGadgets->agadget.hdr.component_id,
                          aGadget->infoGadgets->agadget.data.button.value);
         button_set_value(0,
                          SharesWindId, 
                          aGadget->infoGadgets->next->agadget.hdr.component_id,
                          aGadget->infoGadgets->next->agadget.data.button.value);
      }   
   }

   button_set_validation(0,
                         SharesWindId, 
                         aGadget->agadget.hdr.component_id,
                         aGadget->agadget.data.button.validation);

   return 1;
}

                        
BOOL isPathOk(ObjectId     windowId,
              tpGadgetList aGadget,
              int          serviceIndex)
{                           
   tpGadgetList bGadget;
   BOOL result=True;  
   char pathName[MAXPATHLEN];             
   int  nbytes,ftype,n;
   void *ptr;

   bGadget=aGadget;
   while (bGadget!=NULL)
   {
      if (bGadget->agadget.hdr.type == WritableField_Base &&
          strcmp(bGadget->parmStruct->label,"path")==0)
      {
         ptr = getParamValuePtr(bGadget->parmStruct, serviceIndex);
         writablefield_get_value(0,
                                 windowId,
                                 bGadget->agadget.hdr.component_id,
                                 pathName,
                                 255,
                                 &nbytes);
         n=objectType(pathName,&ftype);
         if (n==0x1000 || n==0x2000 || ftype>=2)
         {
            
         }  
         else
         {
            result=False;
         }               
         break;
      }

      bGadget=bGadget->next;
   }


   return result;
}
         
int isSharesWindOk(ObjectId winId)
{
   int result=0;
   tpGadgetList aGadget; 
   char title[100]; 

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {
      if (winId==aGadget->childWindow)
      {           
         if (isPathOk(aGadget->childWindow,
                      aGadget->childGadgets,
                      aGadget->index.serviceIndex) == True)
         {
            if (haveGadgetFieldsChanged(aGadget->childWindow,
                                        aGadget->childGadgets,
                                        aGadget->index.serviceIndex)==True)
            {
               storeInGadgetFields(aGadget->childWindow,
                                   aGadget->childGadgets,
                                   aGadget->index.serviceIndex); 
               updateSharesWindow(aGadget);   
               window_set_title(0,TopWindId,"Samba Server Configuration *");
               window_set_title(0,SharesWindId,"Shares *");   
               sprintf(title,"%s *",lp_servicename(aGadget->index.serviceIndex));
               window_set_title(0,aGadget->childWindow,title);
               optionsChanged=True;
            }
         }
         else
         {
            toolbox_show_object(0,aGadget->childWindow,0,NULL,0,0);
            wimp_werr(0,"Path must be a directory or image file."); 
         }
         result=1;
         break;
      }
      aGadget=aGadget->next;
   }

   return result;
}
                         
int checkIfShareExists(char* name)
{
   int result = -1;
   tpGadgetList aGadget;

   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {
      if (StrCaseCmp(aGadget->label, name)==0)
      {
         result=aGadget->index.serviceIndex;
         break;
      }
      aGadget=aGadget->next;
   }

   return result;
}


tpGadgetList addNewDirShare(char *buffer)
{             
   int  i;
   tpGadgetList aGadget=NULL;               
   BOOL ret;
   pstring err_str;
   pstring msg_str;

   i = checkIfShareExists(buffer);
   if (i>=0)
   {
      /* already exists */                 
      wimp_werr(0,"Share with same name already exists!");  
      writablefield_set_value(0,newShareMenuId,1,buffer);
      toolbox_show_object(0,newShareMenuId,0,NULL,0,0);
      return NULL;
   }                      
   else
   {
      i=lp_add_new_service(buffer);

      ret = local_password_change(buffer, 
                                  /*trust*/ False, /*add*/ True,/*enable*/ False, 
                                  /*disable_user*/False, /*set_no_password*/True, NULL, 
                                  err_str, sizeof(err_str), msg_str, sizeof(msg_str));    
#if 0
     if(*msg_str)                 
        printf(msg_str);
     if(*err_str)
        fprintf(stderr, err_str);  
#endif

      aGadget=createShareGadget(SharesWindId,i,lastWidth);  

      if (aGadget!=NULL)
      {
         aGadget->index.serviceIndex=i;
         createInfoGadget(aGadget,SharesWindId,i,1,60);
      }

      sortGadgetList(&SharesWindGadgets,
                     offsetof(tGadgetList,label),
                     QSORT_CAST StrCaseCmp);

      redrawNow();
   }
 
   /* 
    * after sort the pointer is not pointing at the one we just add
    * to need to find it in the list!
    */                
   aGadget=SharesWindGadgets;
   while (aGadget!=NULL)
   {
      if (aGadget->index.serviceIndex==i)
      {
         break;
      }

      aGadget=aGadget->next;
   }                                   
  
   window_set_title(0,TopWindId,"Samba Server Configuration *");
   window_set_title(0,SharesWindId,"Shares *");   
   optionsChanged=True;

   return aGadget;
}

int addNewShare(ObjectId winId)
{
   char buffer[MAXPATHLEN];                 
   int  nbytes;                   
   tpGadgetList aGadget;
                                              
   
   writablefield_get_value(0,winId,1,buffer,sizeof(buffer),&nbytes);                 
 
   aGadget=addNewDirShare(buffer); 
                                                
   if (tmpPathPresent==True && aGadget)
      lp_set_path(aGadget->index.serviceIndex,tmpPath);
   else
      tmpPathPresent=False; 

   return 1;
}
                                  


int copyShare(ObjectId winId)
{
   char buffer[MAXPATHLEN];                 
   int  nbytes;                   
   int  i;
   tpGadgetList aGadget;
   int selected;
   tpGadgetList selectedGadget;

   writablefield_get_value(0,winId,0,buffer,sizeof(buffer),&nbytes);
                 
   i = checkIfShareExists(buffer);
   if (i>=0)
   {
      /* already exists */                 
   }                      
   else
   {
      selected = getSelectedGadget(&selectedGadget);

      i=lp_add_service(buffer,selectedGadget->index.serviceIndex);
      copyPassFileEntry(lp_servicename(selectedGadget->index.serviceIndex),
                        lp_servicename(i));

      aGadget=createShareGadget(SharesWindId,i,lastWidth);
      if (aGadget!=NULL)  
      {
         aGadget->index.serviceIndex=i;
         createInfoGadget(aGadget,SharesWindId,i,1,60);
      }

      sortGadgetList(&SharesWindGadgets,
                     offsetof(tGadgetList,label),
                     QSORT_CAST StrCaseCmp);

      
      window_set_title(0,TopWindId,"Samba Server Configuration *");
      window_set_title(0,SharesWindId,"Shares *");   
      optionsChanged=True;

      redrawNow();
   }

   return 1;
}


int renameShare(ObjectId winId)
{
   char buffer[MAXPATHLEN];                 
   int  nbytes;                   
   int  i;
   int selected;
   tpGadgetList selectedGadget;

   writablefield_get_value(0,winId,0,buffer,sizeof(buffer),&nbytes);
                 
   i = checkIfShareExists(buffer);
   if (i>=0)
   {
      /* already exists */                 
   }                      
   else
   {
      selected = getSelectedGadget(&selectedGadget);

      renamePassFileEntry(lp_servicename(selectedGadget->index.serviceIndex),
                          buffer);
      lp_rename_service(selectedGadget->index.serviceIndex,buffer);

    
      strcpy(selectedGadget->label,buffer);

      selectedGadget->agadget.data.button.value=selectedGadget->label;
                                                        
      button_set_value(0,
                       SharesWindId,
                       selectedGadget->agadget.hdr.component_id,
                       selectedGadget->agadget.data.button.value);

      sortGadgetList(&SharesWindGadgets,
                     offsetof(tGadgetList,label),
                     QSORT_CAST StrCaseCmp); 
      
      window_set_title(0,TopWindId,"Samba Server Configuration *");
      window_set_title(0,SharesWindId,"Shares *");   
      optionsChanged=True;

      redrawNow();
   }

   return 1;
}
            


int setSharePassword(ObjectId winId)
{
   char buffer[MAXPATHLEN];                 
   int  nbytes;                   
   int  i;
   int selected;
   tpGadgetList selectedGadget;
   char         passbuf[100];
   BOOL ret;
   pstring err_str;
   pstring msg_str;

   writablefield_get_value(0,winId,0,buffer,sizeof(buffer),&nbytes);
                 
   selected = getSelectedGadget(&selectedGadget);
     
   pass_to_string(buffer,passbuf);

   ret = local_password_change(lp_servicename(selectedGadget->index.serviceIndex), 
                               /*trust*/ False, /*add*/ True,/*enable*/ False, 
                               /*disable_user*/False, /*set_no_password*/False, buffer, 
                               err_str, sizeof(err_str), msg_str, sizeof(msg_str));
    
#if 0
   if(*msg_str)                 
      printf(msg_str);
   if(*err_str)
     fprintf(stderr, err_str);  
#endif
 
   return 1;
}
            



