/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*dboxtcol.c - RISC_OSLib-compatible ColourPicker interface*/

/* Purpose

      Display a dialogue box which shows a true colour value, and which can
   be edited. If the user edits it (or presses OK) then update the colour
   variable and return TRUE. Allow_transparent enables selection of a
   "see-through" colour.

*/

/* History

   14 July 1993 JRC Use ColourPicker, replacing code by A P Thompson.
*/

/*From CLib*/
#include <swis.h>

/*From RISC_OSLib*/
#include "colourpick.h"
#include "event.h"
#include "dboxtcol.h"
#include "help.h"
#include "os.h"
#include "wimp.h"
#include "wimpt.h"
#include "win.h"

#undef  NULL
#define NULL 0

#undef  message_MENUS_DELETED
#define message_MENUS_DELETED 0x400C9

#undef  ColourPicker_OpenDialogue
#define ColourPicker_OpenDialogue 0x47702

static BOOL Open, Chosen;
static dboxtcol_colour Colour;
static dboxtcol_colourhandler Proc;
static void *Handle;
static wimp_w W;
static int Model = 0;

static BOOL Unknowns (wimp_eventstr *event_str, void *h)

{  h = h;

   switch (event_str->e)
   {  case wimp_ESEND:
      case wimp_ESENDWANTACK:
         switch (event_str->data.msg.hdr.action)
         {  case message_MENUS_DELETED:
               Open = FALSE;
               return TRUE;
            break;

            case message_COLOUR_PICKER_COLOUR_CHOICE:
               Chosen = TRUE;

               Colour = (event_str->data.msg.data.words [1] &
                     colourpicker_COLOUR_TRANSPARENT) != 0?
                     dboxtcol_Transparent:
                     event_str->data.msg.data.words [2];

               if (Proc != NULL) (*Proc) (Colour, Handle);
               return TRUE;
            break;

            case message_COLOUR_PICKER_COLOUR_CHANGED:
              Model = event_str->data.msg.data.words [4];
            break;

            case wimp_MHELPREQUEST:
               /*If we get a help-request on this colour picker, we must
                  "handle" it to prevent other parts of RISC_OSLib trying to
                  deal with it.*/
               if (event_str->data.msg.data.helprequest.m.w == W)
                  return TRUE;
            break;
         }
      break;
   }

   return FALSE;
}

BOOL dboxtcol (dboxtcol_colour *colour_out, BOOL allow_transparent,
      char *name, dboxtcol_colourhandler proc, void *handle)

{  BOOL transparent;
   wimp_mousestr mouse_str;
   os_error *error = NULL;
   colourpicker_dialogue dialogue;
   colourpicker_d d;

   static BOOL Added_Messages = FALSE;

   if (!Added_Messages)
   {  static int Messages [] = {message_COLOUR_PICKER_COLOUR_CHOICE,
            message_COLOUR_PICKER_COLOUR_CHANGED, message_MENUS_DELETED, 0};

      if ((error = _swix (Wimp_AddMessages, _IN (0), Messages)) != NULL)
         goto finish;

      Added_Messages = TRUE;
   }

   Open = TRUE;
   Chosen = FALSE;
   Colour = colour_out != NULL? *colour_out: dboxtcol_Transparent;
   Proc = proc;
   Handle = handle;

   transparent = allow_transparent && Colour == dboxtcol_Transparent;

   wimpt_noerr (wimp_get_point_info (&mouse_str));

   dialogue.flags =
      (allow_transparent? colourpicker_DIALOGUE_OFFERS_TRANSPARENT: 0) |
      colourpicker_DIALOGUE_TYPE_CLICK << colourpicker_DIALOGUE_TYPE_SHIFT |
      (transparent? colourpicker_DIALOGUE_TRANSPARENT: 0);
   dialogue.title      = name;
   dialogue.visible.x0 = mouse_str.x;
   dialogue.visible.y0 = 0;
   dialogue.visible.x1 = 0;
   dialogue.visible.y1 = mouse_str.y;
   dialogue.xscroll    = 0;
   dialogue.yscroll    = 0;
   dialogue.colour     = Colour;
   dialogue.size       = 4;
   dialogue.info [0]   = Model;

   if ((error = _swix (ColourPicker_OpenDialogue,
         _IN (0) | _IN (1) | _OUT (0) | _OUT (1),
         colourpicker_OPEN_TRANSIENT | colourpicker_OPEN_SUB_MENU,
         &dialogue, &d, &W)) != NULL)
      goto finish;

   /*Poll the WIMP until the window goes away.*/
   win_add_unknown_event_processor (&Unknowns, 0);
   do event_process (); while (Open);
   win_remove_unknown_event_processor (&Unknowns, 0);

   if (colour_out != NULL) *colour_out = Colour;

finish:
   wimpt_complain (error);
   return Chosen;
}