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

General.c v1.0  22.10.98 Matthew Hampton;

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


#include <muistd.h>
#include <exec/exec.h>
#include "extproc.h"
#include "waveeditclass.c"

void cleanup(void);     /*quit function*/
void Edit_Data(void);

#define ID_DO   1

static struct interface{
    APTR app;
    APTR win;
    
    APTR wave;
    APTR doit;
    APTR exit;
} App;
struct MUI_CustomClass *wave_mcc;


EPP_HANDLE epph;            /*for use with EP_ functions*/
struct sam_info *sample;    /*pointer to a sam_info structure, for collecting data*/
BYTE signal;                /*a signal number, for auto quit (we quit when SamEd quits)*/


LONG main(int argc, char *argv[])
{
    if (argc <3) return(0);
    if (atol(argv[1]) != PROC_MAGIC) return(0); /*make sure SamEd launched us*/

    init();

    if (!(epph = EP_NewPort (atol(argv[2]))))   /*create a new message port*/
        cleanup();

    if (-1 == (signal = EP_AllocQSig (epph) ))  /*allocate the auto quit signal*/
        cleanup();


    /*create the MUI interface*/

    if (!(wave_mcc = MUI_CreateCustomClass(NULL,MUIC_Area,NULL,sizeof(struct WaveData),WaveDispatcher)))
        cleanup();

    App.app = ApplicationObject,
    MUIA_Application_Title      , "General ExtProc",
    MUIA_Application_Version    , "$VER: 1.00 (17.10.98)",
    MUIA_Application_Copyright  , "©1998, Matthew Hampton",
    MUIA_Application_Author     , "Hampy",
    MUIA_Application_Description, "ExtProc for SamED",
    MUIA_Application_Base       , "GENEP",

    SubWindow, App.win = WindowObject,
        MUIA_Window_Title, "General",
        MUIA_Window_ID   , MAKE_ID('G','E','N','E'),

        WindowContents, VGroup,
            Child, App.wave = NewObject(wave_mcc->mcc_Class, NULL,
                    TextFrame,
                    MUIA_Waveform_Draw, WDM_LINE | WDM_HGRID | WDM_VGRID,
                    TAG_DONE),
            Child, HGroup,
                Child, RectangleObject, MUIA_Weight, 25, End,
                Child, App.doit     = SimpleButton("Do"),
                Child, RectangleObject, MUIA_Weight, 25, End,
                Child, App.exit     = SimpleButton("Exit"),
                Child, RectangleObject, MUIA_Weight, 25, End,
                End,
            End,
        End,
    End;

    if(!App.app) cleanup();

    /*return ids (yuk), keep things simple*/
    DoMethod(App.doit,MUIM_Notify,MUIA_Pressed,FALSE,App.app,2,MUIM_Application_ReturnID,ID_DO);
    DoMethod(App.exit,MUIM_Notify,MUIA_Pressed,FALSE,App.app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
    DoMethod(App.win,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,App.app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

    set(App.win,MUIA_Window_Open,TRUE);

    ULONG sigs = 0, ret = 0;
    ULONG quitsig = 1L << signal;    /*use signal bit number to make a mask*/

    while (TRUE)    /*repeat until break*/
    {
        ret = DoMethod(App.app,MUIM_Application_NewInput,&sigs);

        /*check signals for MUI, CTRL_C, and quitsig*/
        if (sigs)
        {
            sigs = Wait(sigs | SIGBREAKF_CTRL_C | quitsig);
            if (sigs & SIGBREAKF_CTRL_C) break;
            if (sigs & quitsig) break;
        }

        /*check for return id's*/
        if (ret)
        {
            if (ret == MUIV_Application_ReturnID_Quit) break;      /*quit if cancelled*/

            if (ret == ID_DO)
            {
                Edit_Data();
            }
        }
    }
    cleanup();  /*quit*/
}


/*cleanup all system allocations, tell samed we have quit*/
void cleanup(void)
{
    EP_Quit (epph);         /*tell SamEd we have quit*/

    EP_DeletePort (epph);   /*delete the message port*/

    EP_DeallocQSig (signal);/*deallocte the autoquit signal*/

    /*close the MUI application*/
    if (App.app)
    {
        set(App.win,MUIA_Window_Open,FALSE);
        MUI_DisposeObject(App.app);          /* dispose all objects. */
        MUI_DeleteCustomClass(wave_mcc); /* delete the custom class. */
        fail(NULL,NULL);
    }
    else
        fail(NULL,"could not open interface (MUI)");
}

void Edit_Data(void)
{
    if (EP_Lock (epph))         /*first aquire the lock*/
    {
        if (EP_GetSample(epph, &sample, NULL, NULL))    /*set up a pointer to the data*/
        {
            /*the length is in bytes but GET / SET_LEVEL offset in samples, so convert to samples*/
            ULONG length = Bytes_To_Sams (sample->length, sample->type);

            for (ULONG n =0; n < length; n++)   /*edit the whole sample*/
            {
                LONG lev = GET_LEVEL (sample->waveform, n, sample->type, 0);
                lev *= lev; lev = lev /90 -180;
                SET_LEVEL (sample->waveform, n, lev, sample->type, 0);
            }
        }

        EP_Unlock(epph);
    }
}

/*if you need to set up new sample data use code similar to this*/

void New_Data(struct sam_info *sample, BYTE *new_wave, ULONG new_len, ULONG new_type)
{
    ULONG new_len_bytes = Sams_To_Bytes (new_len, new_type);

    if (new_wave = AllocMem (new_len_bytes, MEMF_CLEAR | MEMF_PUBLIC))
    {
        if (sample->length)
            FreeMem (sample->waveform, sample->length);

        sample->waveform = new_wave;
        sample->length = new_len_bytes;
        sample->type = new_type;
        sample->loop_begin = 0;
        sample->loop_length = 0;
        sample->loop = FALSE;
        sample->def_freq = 16000;
        sample->def_vol = 65536;
        sample->file_type = 0;      /*Indicates type in sample attributes window, 0 = RAW. No other
                                    values should be used.*/
    }
}
