/*
+--------------------------------------------------------------------+
| PROJECT: MMI-Framework (8417)         $Workfile:: mfw_mmi.c       $|
| $Author:: Es  $ CONDAT GmbH           $Revision:: 8               $|
| CREATED: 21.09.98                     $Modtime:: 1.07.99 10:03    $|
| STATE  : code                                                      |
+--------------------------------------------------------------------+

   MODULE  : MFW_MMI

   PURPOSE : MFW test application

   EXPORT  :

   TO DO   :

   $History:: mfw_mmi.c                                             $
 *
 * *****************  Version 8  *****************
 * User: Es           Date: 6.07.99    Time: 12:21
 * Updated in $/GSM/DEV/MS/SRC/MFW
*/

#define ENTITY_MFW

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#if defined (NEW_FRAME)

#include "typedefs.h"
#include "vsi.h"
#include "pei.h"
#include "custom.h"
#include "gsm.h"

#else

#include "STDDEFS.H"
#include "custom.h"
#include "gsm.h"
#include "vsi.h"

#endif

#include "mfw_mfw.h"
#include "mfw_sys.h"
#include "mfw_win.h"
#include "mfw_edt.h"
#include "mfw_icn.h"
#include "mfw_mnu.h"
#include "mfw_kbd.h"
#include "mfw_tim.h"
#include "dspl.h"
#include "drv_key.h"
#include "drv_tmr.h"

#include "prim.h"
#ifndef PCM_2_FFS
#include "pcm.h"
#endif


#include "mfw_nm.h"
#include "mfw_sim.h"
#include "mfw_cm.h"

#include "mfw_mmi.h"



static U16 scrX, scrY;                  /* sreen size               */
static U8 mfwMem [2048];                /* mfw memory pool          */
//Default colour 
#define MFW_COLOUR			0x00000000,0x00FFFFFF
#define MFW_ICN_COLOUR		0x00000000,0x00FFFFFF

static int initialized = 0;

static void volInit (void);
static void volExit (void);
static void editInit (MfwHnd e);
static void editExit (void);
static void phoneInit (void);
static void phoneExit (void);
static void mainInit (void);
static void mainExit (void);




/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_MMI            |
| STATE   : code                        ROUTINE : mmi_main           |
+--------------------------------------------------------------------+

  PURPOSE : start MMI

*/

void mmi_main (void)
{
    mmiInit();
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_MMI            |
| STATE   : code                        ROUTINE : mmiInit            |
+--------------------------------------------------------------------+

  PURPOSE : initialize application

*/

void mmiInit (void)
{
    if (initialized)
        mmiExit();

    initialized = 1;

    mfwInit(mfwMem,sizeof(mfwMem));     /* MFW INITIALIZATION       */
    winInit(&scrX,&scrY);               /* init window handler      */
    edtInit();                          /* init editor handler      */
    icnInit();                          /* init icon handler        */
    mnuInit();                          /* init menu handler        */
    kbdInit();                          /* init keyboard handler    */
    timInit();                          /* init timer handler       */

                                        /* MMI MODULES SETUP        */
    volInit();                          /* init volume control      */
    mainInit();                         /* init main control        */
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_MMI            |
| STATE   : code                        ROUTINE : mmiExit            |
+--------------------------------------------------------------------+

  PURPOSE : exit application

*/

void mmiExit (void)
{
    if (!initialized)
        return;

    mainExit();
    volExit();

    timExit();                          /* finit timer handler      */
    kbdExit();                          /* finit keyboard handler   */
    mnuExit();                          /* finit menu handler       */
    icnExit();                          /* finit icon handler       */
    edtExit();                          /* finit edit handler       */
    winExit();                          /* finit window handler     */
    mfwExit();                          /* exit mfw                 */

    initialized = 0;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_MMI            |
| STATE   : code                        ROUTINE : volControl         |
+--------------------------------------------------------------------+

  PURPOSE : setup volume control

*/

#define MAX_VOLUME 10

static MfwHnd volWin;                   /* the volume window        */
static MfwHnd volKbd;                   /* the volume keyboard      */
static MfwHnd volTim;                   /* the volume timer         */
static int curVolume;                   /* current volume           */
static U32 curKey;                      /* current key              */

static void volShow (void)
{
    timStop(volTim);
    dspl_ClearAll();
    dspl_TextOut(20,12,DSPL_TXTATTR_NORMAL,"VOLUME");
    dspl_DrawRect(20,22,20+curVolume*6,22+5);
}

static int volEventWin (MfwEvt e, MfwWin *w)
{
    switch (e)
    {
        case MfwWinVisible:
            if (w->flags & MfwWinVisible)
                volShow();
            break;
        default:
            return 0;
    }

    return 1;
}

static int volEventKbd (MfwEvt e, MfwKbd *kc)
{
    curKey = e;
    volShow();
    if (curKey & KEY_MAKE)
        ((MfwTim *) mfwControl(volTim))->time = 500;
    else
        ((MfwTim *) mfwControl(volTim))->time = 2000;
    timStart(volTim);

    return 1;
}

static int volEventTim (MfwEvt e, MfwTim *tc)
{
    if (!(curKey & KEY_MAKE))
    {
        winHide(volWin);
        return 1;
    }

    if (curKey & KEY_VOLUP)
    {
        if (curVolume < MAX_VOLUME)
            curVolume++;
    }
    else
    {
        if (curVolume > 0)
            curVolume--;
    }
    volShow();
    timStart(volTim);

    return 1;
}

static void volInit (void)
{
    U32 events;

    events = KEY_VOLUP + KEY_VOLDOWN + KEY_MAKE;
    curVolume = 3;
    volWin = winCreate(0,0,MfwWinVisible,(MfwCb) volEventWin);
    volKbd = kbdCreate(0,events,(MfwCb) volEventKbd);
    volTim = timCreate(0,2000,(MfwCb) volEventTim);
}

static void volExit (void)
{
    timDelete(volTim);
    kbdDelete(volKbd);
    winDelete(volWin);
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_MMI            |
| STATE   : code                        ROUTINE : editControl        |
+--------------------------------------------------------------------+

  PURPOSE : general editor control

*/

static MfwHnd myHandle = 0;             /* editors handle           */
static MfwHnd editTim;                  /* the editor timer         */

static U8 editControls [KCD_MAX] =      /* edit control keys:       */
{
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    ecBack, ecDel, ecNone, ecNone, ecUp, ecDown, ecLeft, ecRight,
    ecNone, ecNone, ecEnter, ecNone, ecNone, ecNone,
    ecNone, ecNone, ecEnter, ecNone, ecNone, ecNone, ecNone
};

static char editHeader [128];           /* editor information       */
static U8 editAlphaMode;                /* alpha mode flag          */
static U8 editAlphaLevel;               /* alpha level selected     */
static U8 editAlphaKey;                 /* alpha mode current key   */
static U8 editAlpha [10][4] =           /* alpha mode characters    */
{
    {'-','!','?',','},
    {'a','b','c','1'}, {'d','e','f','2'}, {'g','h','i','3'},
    {'j','k','l','4'}, {'m','n','o','5'}, {'p','q','r','6'},
    {'s','t','u','7'}, {'v','w','x','8'}, {'y','z',' ','9'}
};


static void editShowHeader (void)
{
    sprintf(editHeader,"%c [%c]",
        (editAlphaMode)?'A':'N',
        (editAlphaMode && editAlphaKey != KCD_MAX)?
            editAlpha[editAlphaKey][editAlphaLevel]:' ');
    dspl_TextOut(2,0,DSPL_TXTATTR_NORMAL,editHeader);
    dspl_DrawRect(1,8,98,30);
}

static int editEventTim (MfwEvt e, MfwTim *t)
{
    if (!editAlphaMode)
        return 1;

    edtChar(myHandle,editAlpha[editAlphaKey][editAlphaLevel]);
    editAlphaLevel = 3;
    editAlphaKey = KCD_MAX;

    return 1;
}

static int editEventKbd (MfwEvt e, MfwKbd *k)
{
    if (editAlphaMode)
    {
        if (editAlphaKey != KCD_MAX && editAlphaKey != k->code)
        {
            timStop(editTim);
            edtChar(myHandle,editAlpha[editAlphaKey][editAlphaLevel]);
            editAlphaLevel = 3;
            editAlphaKey = KCD_MAX;
        }
        if (k->code <= KCD_9)
        {
            editAlphaKey = k->code;
            editAlphaLevel++;
            if (editAlphaLevel > 3)
                editAlphaLevel = 0;
            editShowHeader();
            timStart(editTim);
            return 1;
        }
    }
    switch (k->code)
    {
        case KCD_CLEAR:
            return 0;
        case KCD_ABC:
            editAlphaMode = (U8) !editAlphaMode;
            if (editAlphaMode)
            {
                editAlphaLevel = 3;
                editAlphaKey = KCD_MAX;
            }
            editShowHeader();
            return 1;
        default:
            break;
    }
    edtChar(myHandle,editControls[k->code]);

    return 1;
}

static void editInit (MfwHnd e)
{
    myHandle = e;
    editTim = timCreate(0,1000,(MfwCb) editEventTim);

    editAlphaLevel = 3;
    editAlphaKey = KCD_MAX;
}

static void editExit (void)
{
    myHandle = 0;
    timDelete(editTim);
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_MMI            |
| STATE   : code                        ROUTINE : PhonebookControl   |
+--------------------------------------------------------------------+

  PURPOSE : setup main window control

*/

static MfwHnd phoneWin;                 /* the phonebook window     */
static MfwHnd phoneKbd;                 /* the phone keyboard       */
static MfwHnd phoneEdt;                 /* the phone editor         */
static MfwHnd phoneOldFocus;            /* previous focus           */

#define PhoneNumSize 32
#define PhoneAlphaSize 224

static struct phoneBookTag
{
    char number [32];
    char alpha [224];
} phoneADN [100] =
{
    {"03039094231","Jie Volckarts"},
    {"03039094267","Karsten Klawon"},
    {"03039094108","Erwin Schmid"},
    {"",""}
};

static int phoneIndex;
static int phoneEditing = 0;
static int phoneFailure = 0;

static MfwEdtAttr phoneEditAttr =
{                                       /* edit attributes:         */
    {3,10,95,20},                       /* edit area                */
    0,0,0,                              /* fg color, font, mode     */
    editControls,                       /* control key array        */
    0,0                                 /* edit buffer, size        */
};


static void phoneSetEdit (void)
{
    if (editAlphaMode)
    {
        phoneEditAttr.text = phoneADN[phoneIndex].alpha;
        phoneEditAttr.size = PhoneAlphaSize;
    }
    else
    {
        phoneEditAttr.text = phoneADN[phoneIndex].number;
        phoneEditAttr.size = PhoneNumSize;
    }
    edtReset(phoneEdt);
}

static void phoneShowHeader (void)
{
    char hdr [8];

    editShowHeader();
    sprintf(hdr," %s%3d",editAlphaMode?" Name ":"Number",phoneIndex);
    dspl_TextOut(39,0,DSPL_TXTATTR_INVERS,hdr);
}

static void phoneShow (void)
{
    dspl_ClearAll();
    phoneShowHeader();
    edtShow(phoneEdt);
}

static int phoneEventWin (MfwEvt e, MfwWin *w)
{
    switch (e)
    {
        case MfwWinVisible:
            if (w->flags & MfwWinVisible)
                phoneShow();
            break;
        default:
            return 0;
    }

    return 1;
}

static int phoneEventKbd (MfwEvt e, MfwKbd *kc)
{
    if (phoneFailure)
    {
        phoneFailure = 0;
        e = KEY_CLEAR;
    }
    if (phoneEditing)
        phoneEditing = editEventKbd(e,kc);
    if (phoneEditing)
        return 1;

    switch (e & ~KEY_MAKE)
    {
        case KEY_MNUUP:
            if (phoneIndex > 0)
                phoneIndex--;
            break;
        case KEY_MNUDOWN:
            if (phoneIndex < 99)
                phoneIndex++;
            break;
        case KEY_ABC:
            editAlphaMode = (U8) !editAlphaMode;
            break;
        case KEY_OK:
            phoneEditAttr.mode = edtCurBar1;
            phoneEditing = 1;
            break;
        case KEY_CLEAR:
            phoneEditAttr.mode = 0;
            phoneEditing = 0;
            winFocus(phoneOldFocus);
            phoneExit();
            return 1;
        default:
            return 1;                   /* superflous !?            */
//            return editEventKbd(e,kc);
    }
    phoneSetEdit();
    winShow(phoneWin);

    return 1;
}

static void phoneInit (void)
{
    U32 keys = 0x7fffffff & ~KEY_VOLUP & ~KEY_VOLDOWN;

    phoneWin = winCreate(0,0,MfwWinVisible,(MfwCb) phoneEventWin);
    phoneKbd = kbdCreate(phoneWin,keys,(MfwCb) phoneEventKbd);
    phoneEdt = edtCreate(phoneWin,&phoneEditAttr,0,0);
    editInit(phoneEdt);
    phoneEditing = 0;
    phoneFailure = 0;
    phoneIndex = 0;                     /* start with index 0       */
}

static void phoneExit (void)
{
    editExit();
    edtDelete(phoneEdt);
    kbdDelete(phoneKbd);
    winDelete(phoneWin);
}

static int viewPhonebook (void)
{
    phoneInit();
    editAlphaMode = 1;                  /* start alphanumeric       */
    phoneSetEdit();
    phoneOldFocus = winFocus(phoneWin); /* make me the first one    */
    winShow(phoneWin);

    return 0;
}

static int searchPhonebook (void)
{
    phoneInit();
    phoneOldFocus = winFocus(phoneWin); /* make me the first one    */
    phoneFailure = 1;
    dspl_ClearAll();
    dspl_TextOut(5,12,DSPL_TXTATTR_NORMAL,"not implemented");
    return 0;
}

static int newPhonebook (void)
{
    phoneInit();
    while (phoneIndex < 99 && (strlen(phoneADN[phoneIndex].alpha)
                           || strlen(phoneADN[phoneIndex].number)))
        phoneIndex++;
    editAlphaMode = 1;                  /* start alphanumeric       */
    phoneSetEdit();
    phoneOldFocus = winFocus(phoneWin); /* make me the first one    */
    winShow(phoneWin);

    return 0;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_MMI            |
| STATE   : code                        ROUTINE : MessagesControl    |
+--------------------------------------------------------------------+

  PURPOSE : setup main window control

*/

static int doMessages (void)
{
    dspl_ClearAll();
    dspl_TextOut(30,12,DSPL_TXTATTR_NORMAL,"Sorry..");
    return 0;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_MMI            |
| STATE   : code                        ROUTINE : mainControl        |
+--------------------------------------------------------------------+

  PURPOSE : setup main window control

*/

static MfwHnd mainWin;                  /* the main window          */
static MfwHnd mainKbd;                  /* the main keyboard        */
static MfwHnd mainTim;                  /* the main timer           */
static MfwHnd mainMnu;                  /* the main menu            */



static char phoneMenuIcons [] =
{
    0x00,0x00,  0x7E,0x7E,  0x41,0x82,  0x59,0x9C, /* VIEW          */
    0x41,0xA2,  0x5D,0xA2,  0x41,0xA2,  0x5D,0x9C,
    0x41,0x82,  0x41,0x82,  0x7F,0xFE,  0x00,0x00,

    0x00,0x00,  0x7E,0x7E,  0x41,0x82,  0x59,0xBA, /* SEARCH        */
    0x41,0x8A,  0x5D,0x92,  0x41,0x92,  0x5D,0x82,
    0x41,0x92,  0x41,0x82,  0x7F,0xFE,  0x00,0x00,

    0x00,0x00,  0x7E,0x7E,  0x41,0x81,  0x59,0xBB, /* NEW           */
    0x41,0x87,  0x5D,0x8E,  0x41,0x8C,  0x5D,0xB2,
    0x41,0x82,  0x41,0x82,  0x7F,0xFE,  0x00,0x00,
};

static MfwIcnAttr phoneMenuIconAttr =
{
    {80,18,16,12},                      /* icon area                */
    3,                                  /* number of icons          */
    phoneMenuIcons,                      /* icon array               */
	MFW_ICN_COLOUR
};

static MfwMnuItem phoneMenuItems [] =
{
    {&phoneMenuIconAttr,0,"VIEW",0,viewPhonebook},
    {&phoneMenuIconAttr,0,"SEARCH",0,searchPhonebook},
    {&phoneMenuIconAttr,0,"NEW",0,newPhonebook}
};

static MfwMnuAttr phoneMenuAttr =
{
    {20,5,80,10},                       /* one menu line            */
    MNU_LEFT,
    phoneMenuItems,
    3,
    MENUCOLOUR_LISTDEF
};


static char mainMenuIcons [] =
{
    0x00,0x00,  0x7E,0x7E,  0x41,0x82,  0x59,0xBA, /* PHONEBOOK     */
    0x41,0x82,  0x5D,0xB2,  0x41,0x82,  0x5D,0x82,
    0x41,0x82,  0x41,0x82,  0x7F,0xFE,  0x00,0x00,

    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00, /* MESSAGES      */
    0x7F,0xFE,  0x50,0x0A,  0x48,0x12,  0x4C,0x32,
    0x52,0x4A,  0x61,0x86,  0x7F,0xFE,  0x00,0x00
};

static MfwIcnAttr mainMenuIconAttr =
{
    {80,18,16,12},                      /* icon area                */
    2,                                  /* number of icons          */
    mainMenuIcons.                       /* icon array               */
	MFW_ICN_COLOUR
};

static MfwMnuItem mainMenuItems [] =
{
    {&mainMenuIconAttr,0," PHONEBOOK",&phoneMenuAttr,0},
    {&mainMenuIconAttr,0," MESSAGES",0,doMessages}
};

static MfwMnuAttr mainMenuAttr =
{
    {20,5,80,18},                       /* two menu lines           */
    MNU_LEFT | MNU_CUR_STAR,
    mainMenuItems,
    2,
    MENUCOLOUR_LISTDEF
};


static void mainShow (void)
{
    timStop(mainTim);
    dspl_ClearAll();
    mnuShow(mainMnu);
}

static int mainEventWin (MfwEvt e, MfwWin *w)
{
    switch (e)
    {
        case MfwWinVisible:
            if (w->flags & MfwWinVisible)
                mainShow();
            break;
        default:
            return 0;
    }

    return 1;
}

static int mainEventTim (MfwEvt e, MfwTim *t)
{
    winShow(mainWin);
    winFocus(mainWin);

    return 1;
}

static int mainEventKbd (MfwEvt e, MfwKbd *kc)
{
    switch (e & ~KEY_MAKE)
    {
        case KEY_MNUUP:
            mnuUp(mainMnu);
            break;
        case KEY_MNUDOWN:
            mnuDown(mainMnu);
            break;
        case KEY_OK:
            mnuSelect(mainMnu);
            break;
        case KEY_CLEAR:
            mnuEscape(mainMnu);
            break;
    }

    return 1;
}

static void mainInit (void)
{
    U32 keys = KEY_MNUUP + KEY_MNUDOWN + KEY_OK + KEY_CLEAR;

    mainWin = winCreate(0,0,MfwWinVisible,(MfwCb) mainEventWin);
    mainTim = timCreate(0,1000,(MfwCb) mainEventTim);
    mainKbd = kbdCreate(0,keys,(MfwCb) mainEventKbd);
    mainMnu = mnuCreate(mainWin,&mainMenuAttr,0,0,0,0);

    timStart(mainTim);
}

static void mainExit (void)
{
    mnuDelete(mainMnu);
    kbdDelete(mainKbd);
    timDelete(mainTim);
    winDelete(mainWin);
}

