/*
 * NAME
 *   example.c - Friday 05-Apr-96 18:53:26
 *
 * AUTHOR
 *   Jon Rocatis
 *
 * DESCRIPTION
 *   Example Apache PlugIn module
 *
 * INFO
 *
 * BUGS
 *
 * TO DO
 *
 */

#include "definclude.h"

int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}

LONG __stack = 8192;

char vers[] = "1.0";

////// GLOBALS //////////

struct MsgPort *apachePort;      // Apache's comm port
struct MsgPort *replyPort;       // The port Apache replies to..
struct Library *ALBase;
BOOL quitByApache = FALSE;

// Stuff for MUI ////////

struct mainwinVars
{
  APTR win,menustrip,btreceive,btsend,str;
  APTR cysort,lv,btcomment,btpatch,btload,btloadall,btsave,btsaveall,btnew,btdelete;
};

APTR app;
struct Library *MUIMasterBase;
struct mainwinVars mw;
struct Screen *screen;

/////////////////////////

#define TALKTOAPACHE(m) TalkToApache((struct Message *)&m, sizeof(m))

void TalkToApache(struct Message *msg, UWORD len)
{
    // Initialize the message structure

    msg->mn_Length = len;
    msg->mn_ReplyPort = replyPort;

    // Send and wait
    
    PutMsg(apachePort, msg);          // Send message to Apache's msgPort
    WaitPort(msg->mn_ReplyPort);      // Wait for answer from Apache
    GetMsg(msg->mn_ReplyPort);        // Remove replied message from queue
}

/////////////////////////

void DisplayMsg(char *msg)
{
  static struct EasyStruct es =
  {
    sizeof(struct EasyStruct),
    0,
    "PlugIn Failed!",
    "%s",
    "Okay",
  };

    EasyRequest(NULL, &es, NULL, msg);
}

/////////////////////

void TestBusyWin(void)
{
  struct BusyVars busy;
  LONG cnt;

    busy.app = app;
    if (alBusyWinOpen(&busy, "Testing the Busy Window"))
    {
      for (cnt = 0; cnt < 20; cnt++)
      {
        Delay(10);
        alBusyWinUpdate(&busy, (cnt*100)/20);
      }
      alBusyWinClose(&busy);
    }
}

/////////////////////

void TestGetNumber(void)
{
  struct GetNumberVars info;
  LONG number;

    info.app = app;
    info.title = "Set Patch #";
    info.initial = 25;
    info.min = 0;
    info.max = 128,

    number = alGetNumber(&info);
}

/////////////////////

BOOL InitApplication(void)
{
    app = ApplicationObject,
      MUIA_Application_Title      , "Example",
      MUIA_Application_Version    , vers,
      MUIA_Application_Copyright  , "© 1996 Jon Rocatis, SideFX",
      MUIA_Application_Author     , "Jon Rocatis",
      MUIA_Application_Description, "Apache Plug-In Module",
      MUIA_Application_Base       , "API_EXAMPLE",
      MUIA_Application_Menustrip, mw.menustrip = MUI_MakeObject(MUIO_MenustripNM,MenuData1,0),
      MUIA_Application_HelpFile,"PROGDIR:Example.guide",

      SubWindow, mw.win = WindowObject,
        MUIA_Window_Title, "Example",
        MUIA_Window_ID, MAKE_ID('M','A','I','N'),
        MUIA_Window_Screen, screen,
        
        WindowContents, VGroup,
          Child, mw.lv = ListviewObject,
            MUIA_Listview_Input, TRUE,
            MUIA_Listview_List, ListObject,
            InputListFrame,
            End,
          End,   
        End,     // Vgroup
      End,  
    End;
      
    if (app)
    {
      DoMethod(mw.win,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
        app,2,MUIM_Application_ReturnID,MW_CLOSEWIN);

      return(TRUE);
    }
    else
      return(FALSE);
}

/////////////////////////

void EventLoop(void)
{
  BOOL running = TRUE;
  ULONG signals, muiSignals, commMask, id;
  ApacheMsgHeader *msg;
  
    commMask = (1L << replyPort->mp_SigBit);
    while (running)
    {
      if (id = DoMethod(app,MUIM_Application_Input,&muiSignals))
      {
        switch(id)
        {
          case MUIV_Application_ReturnID_Quit:
          case MW_CLOSEWIN:
          case MENU_QUIT:
            running = FALSE;
            break;
            
          case MENU_TESTBUSY:
            TestBusyWin();
            break;  

          case MENU_TESTGETNUMBER:
            TestGetNumber();
            break;  
        }    
      }

      if (running && muiSignals)
        signals =  Wait(muiSignals | commMask);

      if (signals & commMask)
      {
        while (msg = (ApacheMsgHeader *)GetMsg(replyPort))
        {
          switch (msg->msgType)
          {
            case AMT_QUIT:
              // Apache wants you to quit. If there are any unsaved changes you should ask
              // the user if it's okay to quit. Set the okToQuit field in the message to
              // TRUE if it's okay. If not set it to FALSE and activate one of your PlugIn's
              // windows.
              
              ((apmQuit *)msg)->okToQuit = TRUE;   // In this example we just quit no matter what..
              running = FALSE;
              quitByApache = TRUE;
              break;
              
            case AMT_ACTIVATE:
              // Apache wants your PlugIn to activate one of its windows.

              set(mw.win,MUIA_Window_Activate,TRUE);
              break;  
          }  
          ReplyMsg(msg);
        }  
      }
    }
}

/////////////////////////

/*
 *
 * Cleans up everything..
 *
 */

void fail(char *msg, long retval)
{
    if (msg)           DisplayMsg(msg);

    if (app)           MUI_DisposeObject(app);
    if (MUIMasterBase) CloseLibrary(MUIMasterBase);
    if (ALBase)        CloseLibrary(ALBase);
    if (replyPort)     DeletePort(replyPort);
    exit(retval);
}

/*
 * Send hello message
 * Tells Apache that we are up and running
 *
 */

void SendHelloMsg(void)
{
  apmHello msgHello;

    msgHello.msgPort      = replyPort;
    msgHello.manufactorID = 1;            // Change this to the ID of your MIDI device's manufactor
    msgHello.modelID      = 1;            // Change this to the ID of your MIDI device's model
    msgHello.amh.msgType  = AMT_HELLO;
    TALKTOAPACHE(msgHello);
    
    // You'll get some info back from Apache. Check out msgtypes.h for more info..
    
    screen = (struct Screen *)msgHello.screen;
}

/////////////////////

void main(void)
{
    app = NULL;
    replyPort = NULL;

    if (!(replyPort = CreatePort(NULL,0))) fail("Not enough memory!", 1);
    
    Forbid();
    apachePort = FindPort(APACHEPORTNAME);
    Permit();

    if (!(apachePort)) fail("Apache not running!", 1);
    if (!(ALBase = OpenLibrary(APACHELIB_NAME, APACHELIB_VMIN))) fail("Couldn't open Apache.library", 1);
    if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN))) fail("Couldn't open muimaster.library", 1);
    if (!(InitApplication())) fail("Couldn't initialize application!", 1);

    set(mw.win,MUIA_Window_Open,TRUE);
        
    SendHelloMsg();       // When we are up and running tell Apache about it..
    EventLoop();

    if (!quitByApache)    // If the user quitted the PlugIn within itself we must tell Apache that we quit
    {
      apmQuit msgQuit;

      msgQuit.amh.msgType  = AMT_QUIT;
      msgQuit.manufactorID = 1;        // Change this to the ID of your MIDI device's manufactor
      msgQuit.modelID      = 1;        // Change this to the ID of your MIDI device's model
      TALKTOAPACHE(msgQuit);
    }
    fail(NULL, 0);
}

