/*******************************************************************************

					CONDAT (UK)

********************************************************************************                                                                              

 This software product is the property of Condat (UK) Ltd and may not be
 disclosed to any third party without the express permission of the owner.                                 
                                                                              
********************************************************************************

 $Project name:	Basic MMI                                                      
 $Project code:	BMI (6349)                                                           
 $Module:		MMI
 $File:		    MmiLists.c
 $Revision:		1.0                                                       
                                                                              
 $Author:		Condat(UK)                                                         
 $Date:		    22/02/01                                                      
                                                                               
********************************************************************************
                                                                              
 Description:

  

********************************************************************************

 $History: MmiLists.c

       xrashmic 5 Oct, 2005 MMI-SPR-29356, MMI-SPR-29357
       Using the MenuSelect Key for requesting the help info in STK menu. Storing the info that 
       MenuSelectKey was pressed in a list view.
                
   	May 24, 2005    REF: CRR 29358  x0021334
	Description: CT_PTCRB 27.22.4.9.8 fails: wrong terminal response
	Fix:	The implementation is now based on timer. After the specified timeout period
	       the control comes back to SAT main menu, if there is no selection done by the user.

	25/10/00			Original Condat(UK) BMI version.	
	   
 $End

*******************************************************************************/

#define ENTITY_MFW

/* includes */
#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 "pconst.cdg"
#include "mconst.cdg"
#include "message.h"
#include "ccdapi.h"
#include "prim.h"
#include "cus_aci.h"
#include "cnf_aci.h"
#include "mon_aci.h"

#include "tok.h"

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




#include "mfw_sys.h"

#include "mfw_mfw.h"
#include "mfw_win.h"
#include "mfw_kbd.h"
#include "mfw_lng.h"
/* SPR#1428 - SH - New Editor changes */
#ifndef NEW_EDITOR
#include "mfw_edt.h"
#endif
#include "mfw_icn.h"
#include "mfw_mnu.h"
#include "mfw_tim.h"

#include "mfw_sim.h"
#include "mfw_cm.h"
#include "mfw_nm.h"
#include "mfw_phb.h"
#include "mfw_mme.h"
#include "mfw_sat.h"
#include "mfw_sms.h"

#include "dspl.h"

#include "ksd.h"
#include "psa.h"

#include "MmiMain.h"
#include "MmiBookController.h"
#include "MmiDummy.h"
#include "MmiDialogs.h"
#include "MmiLists.h"



#include "MmiMenu.h"
#include "mmiCall.h"
#include "Mmiicons.h"
#include "MmiIdle.h"

#include "MmiSoftKeys.h"
#include "MmiSounds.h"
#include "MmiIdle.h"
#include "MmiNetwork.h"
#include "mmiSat_i.h"
#include "MmiAoc.h"

#include "gdi.h"
#include "audio.h"

#include "cus_aci.h"
#include "mfw_ffs.h"
#include "MmiTimers.h"



#include "mmiColours.h"


#ifndef MFW_EVENT_PASSED
#define MFW_EVENT_PASSED 0
#endif

extern MfwRect menuArea;               /* menus display area      */
extern BOOL getMelodyListStatus(void);

typedef enum
{
    E_INIT,
    E_BACK,
    E_RETURN,
    E_ABORT,
    E_EXIT
} e_lists_events;


/*-----------------------------------------------------------------------------
*
* List menu handling functions:
*
*-----------------------------------------------------------------------------*/
// ADDED BY RAVI - 28-11-2005
EXTERN UBYTE mnuDCSType (MfwHnd m, UBYTE listLanguageType);
EXTERN BOOL getScrollStatus(void);
// END RAVI - 28-11-2005


static int listsKeyEvent(MfwEvt event, MfwKbd *keyboard);
static int listsWinEvent(MfwEvt e, MfwWin *w);
static int listsListCbMenu(MfwEvt EventCode, MfwMnu *MenuHandle);
static void lists_exec_cb (T_MFW_HND win, USHORT event, SHORT value, void * parameter);


/*******************************************************************************

 $Function:  listDisplayListMenu  

 $Description:	 Creates a list menu from data stored in NVRAM.

 $Returns:		none.

 $Arguments:	
 
*******************************************************************************/
T_MFW listDisplayListMenu (MfwHnd Parent, ListMenuData *Data, ListCbFunc cbFunc,int inUnicode)
{
    // UBYTE i;  // RAVI - Not Used.
    MfwWin * win;
    MfwHnd winLists;
    T_MFW Status = LISTS_OK;

    TRACE_FUNCTION ("listDisplayListMenu()");

    winLists = winCreate(Parent, 0, E_WIN_VISIBLE, (MfwCb)listsWinEvent);

    if (winLists == NULL)
	{
	    Status = LISTS_FAIL;				/* Inform caller of failure. */
	    TRACE_EVENT ("win creation fails");
	}
    else
	{
	    ListWinInfo * ListData = (ListWinInfo *)ALLOC_MEMORY (sizeof (ListWinInfo));

		if (!ListData)
			{
				/* cq12719. if insufficient memory for listdata then delete window and Free allocated memory.16-03-04.MZ */
				if(NULL != winLists)
					winDelete(winLists);
				
				 TRACE_EVENT ("(ListWinInfo *)ALLOC_MEMORY fails");
				 return LISTS_FAIL;
			}

	    ListData->mmi_control.dialog = (T_DIALOG_FUNC)lists_exec_cb;
	    ListData->mmi_control.data   = ListData;
	    win = ((MfwHdr *)winLists)->data;
	    win->user = (void *) ListData;

	    ListData->Parent = Parent;
	    ListData->Callback = cbFunc;
	    ListData->winLists = winLists;
	    ListData->kbdLists =      kbdCreate(winLists,Data->KeyEvents|KEY_MAKE,         (MfwCb)listsKeyEvent);
	    ListData->kbdLists_long = kbdCreate(winLists,Data->KeyEvents|KEY_LONG,(MfwCb)listsKeyEvent);

	    if ((ListData->kbdLists == NULL) || (ListData->kbdLists_long == NULL))
		{
		    Status = LISTS_FAIL;
			TRACE_EVENT ("ListData->kbdLists fails");
		}
	    else
		{
		    /* Create initial list menu for display. */

		    /*
		     * set menu list from outside
		     */
		    ListData->MenuListsAttr = *Data->Attr; /* copy contents */

		    /* SPR#2492 - DS - Do not overwrite mode settings unless mode is zero */
		    if (ListData->MenuListsAttr.mode == 0x0000) /* Mode not yet setup */
         		    ListData->MenuListsAttr.mode = MNU_LEFT | MNU_LIST | MNU_CUR_LINE;
		    else
        		    ListData->MenuListsAttr.mode |= Data->Attr->mode;
		    
 		    ListData->MenuListsAttr.font = Data->Font; 
		    ListData->MenuListsAttr.items = Data->List;
		    ListData->MenuListsAttr.nItems = Data->ListLength;

		    /*
		     * Intialize List Menu Data
		     */
		    ListData->MenuData = *Data; /* copy contents */
		    ListData->MenuData.listCol = COLOUR_LIST_XX; //Set-up colour
		    ListData->MenuData.Attr = &ListData->MenuListsAttr; /* copy data*/
		    ListData->MenuLists = mnuCreate(winLists, &ListData->MenuListsAttr,
						    E_MNU_SELECT | E_MNU_ESCAPE, 
						    (MfwCb)listsListCbMenu);
			ListData->MenuData.win = winLists;
			Data->win = winLists;
			mnuScrollMode(ListData->MenuLists,1);						
			if (Data->Strings)
				mnuLang (ListData->MenuLists,0);
			else
				mnuLang (ListData->MenuLists,mainMmiLng);

			/* SPR#1983 - SH - Set up whether menu is in unicode or not */
			if (inUnicode != 0)
			{
			    mnuDCSType(ListData->MenuLists, inUnicode); /* Unicode display */
			}
		    mnuChooseVisibleItem(ListData->MenuLists, Data->ListPosition-1);
		    mnuUnhide(ListData->MenuLists);
			TRACE_EVENT ("mmiList winShow()");
		    winShow(winLists);
		}
	}

    return Status;
}


/*******************************************************************************

 $Function:  listsKeyEvent  

 $Description:	 Keyboard event handler

 $Returns:		none.

 $Arguments:	
 
*******************************************************************************/
static int listsKeyEvent (MfwEvt e, MfwKbd *k)
    /* list keyboard event handler */
{
    T_MFW_HND    win  = mfwParent(mfw_header());
    T_MFW_WIN  * win_data = ((T_MFW_HDR *)win)->data;
    ListWinInfo      * data = (ListWinInfo *)win_data->user;
    MfwMnu *MenuHandle;

	
    TRACE_FUNCTION("listsKeyEvent()");
       //xrashmic 5 Oct, 2005 MMI-SPR-29356, MMI-SPR-29357
       //Initialize selectKey to FALSE here. It will be set to TRUE only when a key event for KCD_MNUSELECT occurs.
       data->MenuData.selectKey = FALSE;
	if (!(e & KEY_MAKE))
	{
		return MFW_EVENT_CONSUMED;
	}


    if (e & KEY_LONG)
	{
	    switch (k->code)
		{
		case KCD_HUP: /* back to previous menu */
		    mnuEscape(data->MenuLists);
		    break;
		case KCD_RIGHT: /* Power Down */
		    return MFW_EVENT_PASSED; /* handled by idle */
		default: /* no response to all other keys */
		    return MFW_EVENT_CONSUMED;
		}
	}
    else
	{
	    switch (k->code)
		{
		case KCD_MNUUP: /* highlight previous entry */
		    mnuUp(data->MenuLists);
//GW Not needed?		    winShow(win);
		    // Only required in melody list selection.
		    if(getMelodyListStatus()== TRUE)
		    {
		    	MenuHandle = mfwControl(data->MenuLists);
		    		
		    	data->MenuData.Reason = LISTS_REASON_SCROLL;
				data->MenuData.CursorPosition = MenuHandle->lCursor[MenuHandle->level];
				data->MenuData.ListPosition  = MenuHandle->lCursor[MenuHandle->level]; 
				SEND_EVENT(data->Parent,E_START_MELODY,0,(void*)data);		    
		    }

		    // May 24, 2005    REF: CRR 29358  x0021334
		    // Description: CT_PTCRB 27.22.4.9.8 fails: wrong terminal response
		    // Required when user scrolls list items. Depeneding on this, the timer needs
		    // to be restarted for another 20 seconds.
		    if(getScrollStatus() == TRUE)
		    {
		    	// Send event to indicate that the user has scrolled list items
		     	SEND_EVENT(data->Parent, LISTS_REASON_SCROLL, 0, NULL);	
		    }
		    break;
		case KCD_MNUDOWN: /* highlight next entry */
		    mnuDown(data->MenuLists);
//GW Not needed?		    winShow(win);

		    if(getMelodyListStatus() == TRUE)
			{
			 	MenuHandle = mfwControl(data->MenuLists);
			 	
			 	data->MenuData.Reason = LISTS_REASON_SCROLL;
				data->MenuData.CursorPosition = MenuHandle->lCursor[MenuHandle->level];
				data->MenuData.ListPosition  = MenuHandle->lCursor[MenuHandle->level]; 
				
			    SEND_EVENT(data->Parent,E_START_MELODY,0,(void*)data);
			 }

		      // May 24, 2005    REF: CRR 29358  x0021334
		      // Description: CT_PTCRB 27.22.4.9.8 fails: wrong terminal response
		      // Required when user scrolls list items. Depeneding on this, the timer needs
		      // to be restarted for another 20 seconds.
		      if(getScrollStatus() == TRUE)
		      {
		    	  // Send event to indicate that the user has scrolled list items
		     	  SEND_EVENT(data->Parent, LISTS_REASON_SCROLL, 0, NULL);	
		      }			 			    
		    break;
		case KCD_MNUSELECT:
                //xrashmic 5 Oct, 2005 MMI-SPR-29356, MMI-SPR-29357
                //Menu Select Key was pressed, storing this for future use.
                data->MenuData.selectKey = TRUE;                
                //Break is delibrately not used here. The control should pass through the KCD_LEFT case.
		case KCD_LEFT: /* activate this entry */
		    mnuSelect(data->MenuLists);
		    MenuHandle = mfwControl(data->MenuLists);
			if ((MenuHandle != NULL) && // Marcus: Issue 1810: 12/03/2003
			    (MenuHandle->curAttr != NULL) &&
			    winIsFocussed(win))
			{
					softKeys_displayId( TxtSoftSelect, TxtSoftBack, 0, MenuHandle->curAttr->mnuColour);
			}
		    break;
		case KCD_CALL: /* press send key */
		    data->ExitReason = LISTS_REASON_SEND;
		    data->MenuData.Reason = LISTS_REASON_SEND;
	    	MenuHandle = mfwControl(data->MenuLists);
		    data->MenuData.CursorPosition = MenuHandle->lCursor[MenuHandle->level];
		    data->MenuData.ListPosition  = MenuHandle->lCursor[MenuHandle->level]; /* True cursor position in list menu. */

		    /* SPR998 - SH - check if callback exists before calling it! */
		    if (data->Callback)
		    	data->Callback(data->Parent, &data->MenuData);
		    	
			if (data->MenuData.autoDestroy)
			{
			    winDelete (win);
	    		FREE_MEMORY ((void*)data, sizeof (ListWinInfo));
		    }
		break;
		case KCD_HUP: /* back to previous menu */
		    data->ExitReason = LISTS_REASON_HANGUP;
		    data->MenuData.Reason = LISTS_REASON_HANGUP;
   			/*NM, p023 */
   	    	MenuHandle = mfwControl(data->MenuLists);
		    data->MenuData.CursorPosition = MenuHandle->lCursor[MenuHandle->level];
		    data->MenuData.ListPosition  = MenuHandle->lCursor[MenuHandle->level]; /* True cursor position in list menu. */
   			/*NM, p023 end */
   			
		    data->Callback(data->Parent, &data->MenuData);
			if (data->MenuData.autoDestroy)
			{
			    winDelete (win);
	    		FREE_MEMORY ((void*)data, sizeof (ListWinInfo));
		    }
			break;
		case KCD_RIGHT: /* back to previous menu */
		    mnuEscape(data->MenuLists);
		    break;
		default: /* no response to all other keys */
		    return MFW_EVENT_CONSUMED;
		}
	}
    TRACE_FUNCTION("listsKeyEvent()-end");
    return MFW_EVENT_CONSUMED;
}

/*******************************************************************************

 $Function:  listsWinEvent  

 $Description:	 window event handler

 $Returns:		none.

 $Arguments:	
 
*******************************************************************************/
static int listsWinEvent(MfwEvt e, MfwWin *w)
{
    ListWinInfo * ListData = (ListWinInfo *)w->user;

    TRACE_FUNCTION("listsWinEvent()");

    switch (e)
	{
        case E_WIN_VISIBLE:
            if (w->flags & E_WIN_VISIBLE)
			{
        		dspl_ClearAll();
				softKeys_displayId(ListData->MenuData.LeftSoftKey, ListData->MenuData.RightSoftKey, 0, ListData->MenuListsAttr.mnuColour );
			}
#ifdef FF_MMI_RINGTONE
                    SEND_EVENT(ListData->Parent,E_VISIBLE_MELODY,0,(void*)ListData);                  
#endif
	    	break;
#ifdef FF_MMI_RINGTONE
        case MfwWinSuspend:
		 SEND_EVENT(ListData->Parent,E_SUSPEND_MELODY,0,(void*)ListData); 	
		 break;	
#endif
        default:
	    return MFW_EVENT_PASSED;
	  //  break;   // RAVI
	}
    return MFW_EVENT_CONSUMED;
}

static void lists_exec_cb (T_MFW_HND win, USHORT event, SHORT value, void * parameter)
{
    T_MFW_WIN      * win_data = ((T_MFW_HDR *) win)->data;
    ListWinInfo    * ListData = (ListWinInfo *)win_data->user;
    T_MFW_HND      * l_parent;
    SHORT            l_id;

    TRACE_FUNCTION ("lists_exec_cb()");

    switch (event)
	{
	case E_INIT:
	case E_BACK:
	case E_RETURN:
	case E_ABORT:
	case E_EXIT:
	    /* defaultreaction */
	    l_parent = ListData->Parent;
	    l_id = ListData->id;
	    winDelete (win);
	    FREE_MEMORY ((void*) ListData, sizeof (ListWinInfo));
	    SEND_EVENT (l_parent, event, l_id, NULL); /* forward event to parent */
	    break;
	default:
	    return;
	}
}



/*******************************************************************************

 $Function:  listsListCbMenu  

 $Description:	 List menu handler. (mfw callback function)

 $Returns:		none.

 $Arguments:	
 
*******************************************************************************/
int listsListCbMenu(MfwEvt EventCode, MfwMnu *MenuHandle)
{
    int Status = LISTS_OK;
    T_MFW_HND   win      = mfw_parent (mfw_header());
    T_MFW_WIN * win_data = ((T_MFW_HDR *)win)->data;
    ListWinInfo* ListData = (ListWinInfo *)win_data->user;

    TRACE_FUNCTION("listsCbMenu()");

    switch (EventCode)
	{
        case E_MNU_SELECT:
	    ListData->ExitReason = E_MNU_SELECT;
	    ListData->MenuData.Reason = LISTS_REASON_SELECT;// MZ 14/2/01 E_MNU_SELECT;
	    ListData->MenuData.CursorPosition = MenuHandle->lCursor[MenuHandle->level];
	    ListData->MenuData.ListPosition  = MenuHandle->lCursor[MenuHandle->level]; /* True cursor position in list menu. */
	    /* SPR998 - SH - check if callback exists before calling it! */
		if (ListData->Callback)
	    	ListData->Callback(ListData->Parent, &ListData->MenuData);
	    break;

        case E_MNU_ESCAPE:
	    ListData->ExitReason = LISTS_REASON_BACK;
	    ListData->MenuData.Reason = LISTS_REASON_BACK;
	    /*NM, p023*/
	    ListData->MenuData.CursorPosition = MenuHandle->lCursor[MenuHandle->level];
	    ListData->MenuData.ListPosition  = MenuHandle->lCursor[MenuHandle->level]; /* True cursor position in list menu. */
	    /*NM, p023*/
	    
	    /* SPR998 - SH - check if callback exists before calling it! */
		if (ListData->Callback)
	    	ListData->Callback(ListData->Parent, &ListData->MenuData);
	    break;

        default:
	    Status = LISTS_FAIL;
	    TRACE_EVENT("Activation 77 error"); 
	    break;
	}

    /*
     * Free all allocated memory and handler
     */
	if (ListData->MenuData.autoDestroy)
	{
	    winDelete (win);
    	FREE_MEMORY ((void*) ListData, sizeof (ListWinInfo));
    }
    return Status;
}

void listsDestroy(T_MFW_HND win)
{
   T_MFW_WIN      * win_data = ((T_MFW_HDR *) win)->data;
   ListWinInfo * ListData = (ListWinInfo *)win_data->user;
    winDelete (win);
   	FREE_MEMORY ((void*) ListData, sizeof (ListWinInfo));
    
}

