/*--------------------------------------------------------------------------*
          __                            __ __          __
        _/ /_                          / //_/         / /
       /  __/______ ______ ______ ____/ /__   ______ / /
       / /  / __  // __  // ____// __  // /  / __  // /
      / /_ / /_/ // / / // __/_ / /_/ // /_ / __  // /_
     /___//_____//_/ /_//_____//_____//___//_/ /_//___/

            (c) Copyright 1993 Tobias Ferber, All Rights Reserved.

 *--------------------------------------------------------------------------*/

#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>

#include "atdt.h"
#include "button.h"

static char rcs_id[]= "$VER: $Id: tonedial.c,v 1.1 93/03/29 02:45:25 tf Exp $";

/*
 * The NewWindow stucture's Width and Height are suitable for our graphics
 * under versions of Kickstart 1.3 with  BorderLeft   = 4
 *                                       BorderRight  = 4
 *                                       BorderTop    = 11  (topaz.font,8)
 *                                       BorderBottom = 2
 * If we find differences to these values in the Workbench Screen structure
 * we'll change them accordingly.
 */

static struct NewWindow NewDialWindow= {
  200,70,135,77,0,1,
  CLOSEWINDOW|GADGETDOWN|VANILLAKEY,
  WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|RMBTRAP|SMART_REFRESH|ACTIVATE,
  NULL,NULL,(UBYTE *)"ToneDial",
  NULL,NULL,
  0,0,0,0,
  WBENCHSCREEN
};

static struct Gadget *DialGadgets[16+1];
static struct Window *DialWindow;

void CloseDialWindow(void)
{
  if(DialWindow) CloseWindow(DialWindow);
  for(int i=0; i<16; i++)
  { struct Gadget *g= DialGadgets[i];
    if(g) FreeButton(g);
  }
}

int OpenDialWindow(void)
{
  struct Screen s;

  if(GetScreenData(&s,sizeof(struct Screen),WBENCHSCREEN,NULL))
  { short dx= s.WBorLeft,
          dy= s.WBorTop  + s.RastPort.TxHeight +1,

          /* The title bar height of a window is calculated from the
           * screen's WBorTop field, plus the font height, plus one
           */

          hc= s.WBorRight  + dx,
          vc= s.WBorBottom + dy;

    NewDialWindow.Width  += hc-8;
    NewDialWindow.Height += vc-13;

    /* Note: ToneDial() will take advantage of the circumstances
     * that (1) the GadgetID is equal to the index on DialGadgets[]
     * and that (2) this value can be directly used as dial tone code
     * for play()
     */

    DialGadgets[ 0]= CreateButton(dx+ 9, dy+ 6, 25, 13, "1",  0);
    DialGadgets[ 1]= CreateButton(dx+34, dy+ 6, 25, 13, "2",  1);
    DialGadgets[ 2]= CreateButton(dx+59, dy+ 6, 25, 13, "3",  2);
    DialGadgets[ 3]= CreateButton(dx+93, dy+ 6, 25, 13, "A",  3);
    DialGadgets[ 4]= CreateButton(dx+ 9, dy+19, 25, 13, "4",  4);
    DialGadgets[ 5]= CreateButton(dx+34, dy+19, 25, 13, "5",  5);
    DialGadgets[ 6]= CreateButton(dx+59, dy+19, 25, 13, "6",  6);
    DialGadgets[ 7]= CreateButton(dx+93, dy+19, 25, 13, "B",  7);
    DialGadgets[ 8]= CreateButton(dx+9,  dy+32, 25, 13, "7",  8);
    DialGadgets[ 9]= CreateButton(dx+34, dy+32, 25, 13, "8",  9);
    DialGadgets[10]= CreateButton(dx+59, dy+32, 25, 13, "9", 10);
    DialGadgets[11]= CreateButton(dx+93, dy+32, 25, 13, "C", 11);
    DialGadgets[12]= CreateButton(dx+9,  dy+45, 25, 13, "*", 12);
    DialGadgets[13]= CreateButton(dx+34, dy+45, 25, 13, "0", 13);
    DialGadgets[14]= CreateButton(dx+59, dy+45, 25, 13, "#", 14);
    DialGadgets[15]= CreateButton(dx+93, dy+45, 25, 13, "D", 15);
    DialGadgets[16]= (struct Gadget *)NULL;

    for(int i=0; i<16; i++)
    { struct Gadget *g= DialGadgets[i];
      if(g) g->NextGadget= DialGadgets[i+1];
      else return(2);
    }

    NewDialWindow.FirstGadget= DialGadgets[0];

    DialWindow= (struct Window *)OpenWindow(&NewDialWindow);

    if(!DialWindow)
      return(3);

    RefreshWindowFrame(DialWindow);
    return(0);
  }
  return(1);
}

/*
 * play a touch tone without delaytime.
 */

void play(short n)
{ struct IOAudio *a0= alloc_dtone(),
                 *a1= alloc_dtone();
  if(a0 && a1) play_dtone(a0,a1,n);
  if(a0) free_dtone(a0);
  if(a1) free_dtone(a1);
}


void ToneDial(void)
{
  if(OpenDialWindow()==0)
  {
    BOOL running= TRUE;

    while(running)
    {
      struct IntuiMessage *imsg;
      ULONG class;
      USHORT code;
      struct Gadget *g;

      Wait(1L<<DialWindow->UserPort->mp_SigBit);
      while(imsg=(struct IntuiMessage *)GetMsg(DialWindow->UserPort))
      { class = imsg->Class;
        code  = imsg->Code;
        g     = (struct Gadget *)imsg->IAddress;
        ReplyMsg(imsg);

        switch(class)
        {
          case CLOSEWINDOW:
            running= FALSE;
            break;

          case GADGETDOWN:
            play(g->GadgetID);
            break;

          case VANILLAKEY:
          { long magic= -1;

            switch((UBYTE)code)
            { case '0':  magic= 13; break;
              case '1':  magic=  0; break;
              case '2':  magic=  1; break;
              case '3':  magic=  2; break;
              case '4':  magic=  4; break;
              case '5':  magic=  5; break;
              case '6':  magic=  6; break;
              case '7':  magic=  8; break;
              case '8':  magic=  9; break;
              case '9':  magic= 10; break;
              case '*':  magic= 12; break;
              case '#':  magic= 14; break;
              case 'a':
              case 'A':  magic=  3; break;
              case 'b':
              case 'B':  magic=  7; break;
              case 'c':
              case 'C':  magic= 11; break;
              case 'd':
              case 'D':  magic= 15; break;

              case 27: /* ESC */
                running=FALSE;
                break;
            }

            if(magic>=0)
            { g= DialGadgets[magic];
              ToggleButton(DialWindow,g);
              play(magic);
              ToggleButton(DialWindow,g);
            }
          }
          break;
        }
      }
    }
  }
  CloseDialWindow();
}
