/**                                          
 * Scout - The Amiga System Monitor
 *
 *------------------------------------------------------------------
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * You must not use this source code to gain profit of any kind!
 *
 *------------------------------------------------------------------
 *
 * @author Andreas Gelhausen
 * @author Richard Körber <rkoerber@gmx.de>
 */

#include "system_headers.h"

static void SetDetails( struct IClass *cl,
                        Object *obj,
                        struct AudioModeEntry *ame )
{
    struct AudioModesDetailWinData *amdwd = INST_DATA(cl, obj);
    UBYTE *tmp, *tmp2;

    tmp = tbAllocVecPooled(globalPool, PATH_LENGTH);
    tmp2 = tbAllocVecPooled(globalPool, PATH_LENGTH);
    if (tmp && tmp2) {
        struct MsgPort *mp;

        if (mp = CreateMsgPort()) {
            struct AHIRequest *ahir;

            if (ahir = CreateIORequest(mp, sizeof(struct AHIRequest))) {
                ahir->ahir_Version = 4;

                if (OpenDevice(AHINAME, 0, ahir, 0) == 0) {
                    struct Device *AHIBase;
                    ULONG bits, maxchannels, minfreq, maxfreq, numfreqs, maxplaysamp, maxrecsamp;
                    Fixed minmonivol, maxmonivol;
                    Fixed mininputgain, maxinputgain;
                    Fixed minoutputvol, maxoutputvol;
                    ULONG volume, stereo, panning, hifi, pingpong, record, fullduplex, realtime;
                    UBYTE tmp3[NUMBER_LENGTH], tmp4[NUMBER_LENGTH];

                    AHIBase = ahir->ahir_Std.io_Device;

                    MySetContents(amdwd->amdwd_AudioModeMoreText[0], ame->ame_Name);
                    MySetContents(amdwd->amdwd_AudioModeMoreText[1], ame->ame_Id);

                    AHI_GetAudioAttrs(ame->ame_ModeID, NULL, AHIDB_Driver, tmp, AHIDB_BufferLen, PATH_LENGTH, TAG_DONE);
                    MySetContents(amdwd->amdwd_AudioModeMoreText[2], "DEVS:AHI/%s.audio", tmp);

                    AHI_GetAudioAttrs(ame->ame_ModeID, NULL, AHIDB_Version, tmp, AHIDB_BufferLen, PATH_LENGTH, TAG_DONE);
                    MySetContentsHealed(amdwd->amdwd_AudioModeMoreText[3], tmp);

                    AHI_GetAudioAttrs(ame->ame_ModeID, NULL, AHIDB_Author, tmp, AHIDB_BufferLen, PATH_LENGTH, TAG_DONE);
                    MySetContentsHealed(amdwd->amdwd_AudioModeMoreText[4], tmp);

                    AHI_GetAudioAttrs(ame->ame_ModeID, NULL, AHIDB_Copyright, tmp, AHIDB_BufferLen, PATH_LENGTH, TAG_DONE);
                    MySetContentsHealed(amdwd->amdwd_AudioModeMoreText[5], tmp);

                    AHI_GetAudioAttrs(ame->ame_ModeID, NULL, AHIDB_Annotation, tmp, AHIDB_BufferLen, PATH_LENGTH, TAG_DONE);
                    MySetContentsHealed(amdwd->amdwd_AudioModeMoreText[6], tmp);

                    AHI_GetAudioAttrs(ame->ame_ModeID, NULL, AHIDB_Bits, &bits,
                                                             AHIDB_MaxChannels, &maxchannels,
                                                             AHIDB_MinMixFreq, &minfreq,
                                                             AHIDB_MaxMixFreq, &maxfreq,
                                                             AHIDB_MaxMixFreq, &maxfreq,
                                                             AHIDB_Frequencies, &numfreqs,
                                                             AHIDB_MaxPlaySamples, &maxplaysamp,
                                                             AHIDB_MaxRecordSamples, &maxrecsamp,
                                                             AHIDB_Volume, &volume,
                                                             AHIDB_Stereo, &stereo,
                                                             AHIDB_Panning, &panning,
                                                             AHIDB_HiFi, &hifi,
                                                             AHIDB_PingPong, &pingpong,
                                                             AHIDB_Record, &record,
                                                             AHIDB_FullDuplex, &fullduplex,
                                                             AHIDB_Realtime, &realtime,
                                                             AHIDB_MinMonitorVolume, &minmonivol,
                                                             AHIDB_MaxMonitorVolume, &maxmonivol,
                                                             AHIDB_MinInputGain, &mininputgain,
                                                             AHIDB_MaxInputGain, &maxinputgain,
                                                             AHIDB_MinOutputVolume, &minoutputvol,
                                                             AHIDB_MaxOutputVolume, &maxoutputvol,
                                                             TAG_DONE);

                    MySetContents(amdwd->amdwd_AudioModeMoreText[7], MUIX_R "%lD", bits);
                    if (numfreqs > 1) {
                        MySetContents(amdwd->amdwd_AudioModeMoreText[8], MUIX_R "%6lD Hz", minfreq);
                        MySetContents(amdwd->amdwd_AudioModeMoreText[12], MUIX_R "%6lD Hz", maxfreq);
                    } else {
                        MySetContents(amdwd->amdwd_AudioModeMoreText[8], MUIX_R "---");
                        MySetContents(amdwd->amdwd_AudioModeMoreText[12], MUIX_R "---");
                    }
                    MySetContents(amdwd->amdwd_AudioModeMoreText[9], MUIX_R "%lD", maxplaysamp);
                    MySetContents(amdwd->amdwd_AudioModeMoreText[11], MUIX_R "%lD", maxchannels);
                    MySetContents(amdwd->amdwd_AudioModeMoreText[13], MUIX_R "%lD", maxrecsamp);

                    tmp[0] = 0x00;
                    tmp2[0] = 0x00;

                    if (minmonivol == maxmonivol && minmonivol == 0) {
                        stccpy(tmp3, "<none>\n", sizeof(tmp3));
                        stccpy(tmp4, "<none>\n", sizeof(tmp4));
                    } else {
                        _snprintf(tmp3, sizeof(tmp3), "%ld%%\n", minmonivol * 100 >> 16);
                        _snprintf(tmp4, sizeof(tmp4), "%ld%%\n", maxmonivol * 100 >> 16);
                    }
                    _strcatn(tmp, tmp3, PATH_LENGTH);
                    _strcatn(tmp2, tmp4, PATH_LENGTH);
                    if (mininputgain == maxinputgain) {
                        stccpy(tmp3, "<none>\n", sizeof(tmp3));
                        stccpy(tmp4, "<none>\n", sizeof(tmp4));
                    } else {
                        _snprintf(tmp3, sizeof(tmp3), "%ld%%\n", mininputgain * 100 >> 16);
                        _snprintf(tmp4, sizeof(tmp4), "%ld%%\n", maxinputgain * 100 >> 16);
                    }
                    _strcatn(tmp, tmp3, PATH_LENGTH);
                    _strcatn(tmp2, tmp4, PATH_LENGTH);
                    if (minoutputvol == maxoutputvol) {
                        stccpy(tmp3, "<none>", sizeof(tmp3));
                        stccpy(tmp4, "<none>", sizeof(tmp4));
                    } else {
                        _snprintf(tmp3, sizeof(tmp3), "%ld%%", minoutputvol * 100 >> 16);
                        _snprintf(tmp4, sizeof(tmp4), "%ld%%", maxoutputvol * 100 >> 16);
                    }
                    _strcatn(tmp, tmp3, PATH_LENGTH);
                    _strcatn(tmp2, tmp4, PATH_LENGTH);

                    MySetContents(amdwd->amdwd_AudioModeMoreText[10], MUIX_R "%s", tmp);
                    MySetContents(amdwd->amdwd_AudioModeMoreText[14], MUIX_R "%s", tmp2);
                    set(amdwd->amdwd_AudioModeMoreCheckmark[0], MUIA_Selected, volume);
                    set(amdwd->amdwd_AudioModeMoreCheckmark[1], MUIA_Selected, stereo);
                    set(amdwd->amdwd_AudioModeMoreCheckmark[2], MUIA_Selected, panning);
                    set(amdwd->amdwd_AudioModeMoreCheckmark[3], MUIA_Selected, hifi);
                    set(amdwd->amdwd_AudioModeMoreCheckmark[4], MUIA_Selected, pingpong);
                    set(amdwd->amdwd_AudioModeMoreCheckmark[5], MUIA_Selected, record);
                    set(amdwd->amdwd_AudioModeMoreCheckmark[6], MUIA_Selected, fullduplex);
                    set(amdwd->amdwd_AudioModeMoreCheckmark[7], MUIA_Selected, realtime);

                    CloseDevice(ahir);
                } else {
                    MyRequest(msgErrorContinue, msgCantOpenAHIDevice, AHINAME, ahir->ahir_Version);
                }

                DeleteIORequest(ahir);
            }

            DeleteMsgPort(mp);
        }
    }

    if (tmp) tbFreeVecPooled(globalPool, tmp);
    if (tmp2) tbFreeVecPooled(globalPool, tmp2);

    set(obj, MUIA_Window_Title, MyGetChildWindowTitle("AUDIOMODE", ame->ame_Name, amdwd->amdwd_Title, sizeof(amdwd->amdwd_Title)));
}

static ULONG __saveds mNew( struct IClass *cl,
                            Object *obj,
                            struct opSet *msg )
{
    APTR amodemoretext[15];
    APTR amodemorecheck[8];

    if (obj = (Object *)DoSuperNew(cl, obj,
        MUIA_HelpNode, AudioModesText,
        MUIA_Window_ID, MakeID('.','A','M','D'),
        WindowContents, VGroup,

            Child, ColGroup(2),
                Child, MyLabel2("Name:"),
                Child, HGroup,
                    Child, amodemoretext[0] = MyTextObject(),
                    Child, MyLabel2("ID:"),
                    Child, amodemoretext[1] = MyTextObject2(),
                End,
                Child, MyLabel2("Driver:"),
                Child, amodemoretext[2] = MyTextObject(),
                Child, MyLabel2("Version:"),
                Child, amodemoretext[3] = MyTextObject(),
                Child, MyLabel2("Author:"),
                Child, amodemoretext[4] = MyTextObject(),
                Child, MyLabel2("Copyright:"),
                Child, amodemoretext[5] = MyTextObject(),
                Child, MyLabel2("Annotation:"),
                Child, amodemoretext[6] = MyTextObject(),
            End,
            Child, HGroup,
                Child, VGroup,
                    Child, MyLabel2("Bits:"),
                    Child, MyLabel2("min. Mix Frequency:"),
                    Child, MyLabel2("max. Play Samples"),
                    Child, MyLabel2("min. Monitor Volume:\nmin. Input Gain:\nmin. Output Volume:"),
                End,
                Child, VGroup, MUIA_Group_SameWidth, TRUE, MUIA_Weight, 0,
                    Child, amodemoretext[7] = MyTextObject(),
                    Child, amodemoretext[8] = MyTextObject(),
                    Child, amodemoretext[9] = MyTextObject(),
                    Child, amodemoretext[10] = MyTextObject(),
                End,
                Child, HSpace(0),
                Child, VGroup,
                    Child, MyLabel2("max. Channels:"),
                    Child, MyLabel2("max. Mix Frequency:"),
                    Child, MyLabel2("max. Record Samples"),
                    Child, MyLabel2("max. Monitor Volume:\nmax. Input Gain:\nmax. Output Volume:"),
                End,
                Child, VGroup, MUIA_Group_SameWidth, TRUE, MUIA_Weight, 0,
                    Child, amodemoretext[11] = MyTextObject(),
                    Child, amodemoretext[12] = MyTextObject(),
                    Child, amodemoretext[13] = MyTextObject(),
                    Child, amodemoretext[14] = MyTextObject(),
                End,
            End,
            Child, ColGroup(11),
                Child, amodemorecheck[0] = MyCheckmarkImage(),
                Child, LLabel("Volume"),
                Child, HSpace(0),

                Child, amodemorecheck[1] = MyCheckmarkImage(),
                Child, LLabel("Stereo"),
                Child, HSpace(0),

                Child, amodemorecheck[2] = MyCheckmarkImage(),
                Child, LLabel("Panning"),
                Child, HSpace(0),

                Child, amodemorecheck[3] = MyCheckmarkImage(),
                Child, LLabel("HiFi"),

                Child, amodemorecheck[4] = MyCheckmarkImage(),
                Child, LLabel("PingPong"),
                Child, HSpace(0),

                Child, amodemorecheck[5] = MyCheckmarkImage(),
                Child, LLabel("Record"),
                Child, HSpace(0),

                Child, amodemorecheck[6] = MyCheckmarkImage(),
                Child, LLabel("FullDuplex"),
                Child, HSpace(0),

                Child, amodemorecheck[7] = MyCheckmarkImage(),
                Child, LLabel("RealTime"),
            End,
        End,
        TAG_MORE, msg->ops_AttrList))
    {
        struct AudioModesDetailWinData *amdwd = INST_DATA(cl, obj);
        APTR parent;

        CopyMem(amodemoretext, amdwd->amdwd_AudioModeMoreText, sizeof(amdwd->amdwd_AudioModeMoreText));
        CopyMem(amodemorecheck, amdwd->amdwd_AudioModeMoreCheckmark, sizeof(amdwd->amdwd_AudioModeMoreCheckmark));

        // set(obj, MUIA_Window_ActiveObject, amodemoretext1);

        parent = (APTR)GetTagData(MUIA_Window_ParentWindow, (ULONG)NULL, msg->ops_AttrList);

        DoMethod(parent, MUIM_Window_AddChildWindow, obj);
        DoMethod(obj,    MUIM_Notify,              MUIA_Window_CloseRequest, TRUE,  MUIV_Notify_Application, 5, MUIM_Application_PushMethod, parent, 2, MUIM_Window_RemChildWindow, obj);
    }

    return (ULONG)obj;
}

static ULONG __saveds mDispose( struct IClass *cl,
                                Object *obj,
                                struct opSet *msg )
{
    set(obj, MUIA_Window_Open, FALSE);

    return (DoSuperMethodA(cl, obj, msg));
}

static ULONG __saveds mSet( struct IClass *cl,
                            Object *obj,
                            Msg msg )
{
    struct TagItem *tags, *tag;

    for (tags = ((struct opSet *)msg)->ops_AttrList; tag = NextTagItem(&tags); ) {
        switch (tag->ti_Tag) {
            case MUIA_Window_ParentWindow:
                DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Application, 5, MUIM_Application_PushMethod, tag->ti_Data, 2, MUIM_Window_RemChildWindow, obj);
                break;

            case MUIA_AudioModesDetailWin_AudioMode:
                SetDetails(cl, obj, (struct AudioModeEntry *)tag->ti_Data);
                break;
        }
    }

    return (DoSuperMethodA(cl,obj,msg));
}

ULONG __asm __saveds AudioModesDetailWinDispatcher( register __a0 struct IClass *cl,
                                                     register __a2 Object *obj,
                                                     register __a1 Msg msg )
{
    switch (msg->MethodID) {
        case OM_NEW:     return (mNew(cl, obj, (APTR)msg));
        case OM_DISPOSE: return (mDispose(cl, obj, (APTR)msg));
        case OM_SET:     return (mSet(cl, obj, (APTR)msg));
    }

    return (DoSuperMethodA(cl, obj, msg));
}

