/*
 * AdvancedMenu.h
 *
 * Copyright (C) 2018 OPTOELECTRONICS CO.,LTD. All rights reserved.
 */

#ifndef INCLUDE_ADVENCEDMENU_H_
#define INCLUDE_ADVENCEDMENU_H_

#include <stdlib.h>
#include <stdbool.h>

//////////////////////////////////////////////////////////
// Menu control
//////////////////////////////////////////////////////////

//Event
#define AMENU_CHECK_CHANGED		(0x10000001)
#define AMENU_TEXT_CHANGED		(0x10000002)
#define AMENU_FOCUS_CHANGED		(0x10000003)
#define AMENU_BARCODE_READ		(0x10000004)
#define AMENU_SPECIAL_KEY		(0x10000005)
#define AMENU_BEGIN_CANDIDATE	(0x10000006)
#define AMENU_UPDATE_CANDIDATE	(0x10000007)
#define AMENU_CALLBACK_BREAK	(0x10000008)

#define AM_SELECT_NO_ID (-1)
#define AM_SELECT_ANY_ID (-2)
#define AM_NO_LINE_SELECTED (-1)
#define AM_SELECT_ANY_LINE (-2)
#define AM_SELECT_NO_LINE (-3)

//Control
#define AM_NO_CONTROL 		0
#define AM_TEXT_EDIT  		1
#define AM_SHIFT_MODE 		2
#define AM_SHIFT_CANDIDATE	3
#define AM_CHECK_BOX  		4
#define AM_RADIO_BTN  		5
#define AM_BMPFILE    		6
#define AM_LIST_MARK  		7
#define AM_JUMP_MARK  		8
#define AM_CLEAR_ICON		100
#define AM_ENT_ICON			101
#define AM_SCAN_ICON		102
#define AM_F1_ICON			103
#define AM_F2_ICON			104
#define AM_F3_ICON			105
#define AM_Q1_ICON			106
#define AM_Q2_ICON			107
#define AM_BS_ICON			108
#define AM_1_ICON			109
#define AM_2_ICON			110
#define AM_3_ICON			111
#define AM_4_ICON			112
#define AM_5_ICON			113
#define AM_6_ICON			114
#define AM_7_ICON			115
#define AM_8_ICON			116
#define AM_9_ICON			117
#define AM_0_ICON			118
#define AM_ASTER_ICON		119

//Color palette for menu items
typedef struct{
	int ForeColor;
	int BackColor;
	int Select_ForeColor;
	int Select_BackColor;
	int Control_ForeColor; //Color of control such as CheckBox, RadioButton and KeyIcon.
} AM_ColorPalette, *pAM_ColorPalette;

//Options for menu
typedef struct{
	int MenuForeColor;			//Fore color of menu
	int MenuDisabledForeColor;	//Color of disabled items
	int MenuBackColor;			//Back color of menu
	int NumberOfColorPalette;
	pAM_ColorPalette ColorPalettes; // Color palettes for menu items
	int OptionFlag;
	unsigned int DefaultFont;	//Overrides default font. Default value of the library is LARGE_FONT for App and MEDIUM_FONT for OS. If this member is 0, default value of the library will be used.
	int DefaultLineSpacing;		//Overrides default LineSpacing. Default value of the library is 1 for App and 0 for OS.
	int SpecialKey1;
	int SpecialKey2;
	unsigned int SpecialKeyHoldTime;		//Specify hold time of special keys. Holding down both special keys for SpecialKeyHoldTime(ms) fires AMENU_SPECIAL_KEY event.
} AM_Option, *pAM_Option;

// Bit flags for AM_Option.OptionFlag
#define AM_ALLOW_AUTOREPEAT	0x00000001
#define AM_ALLOW_ROUND_UP	0x00000002	// Valid for AL_CreateList() only.
#define AM_USE_SPECIAL_KEY	0x00000004	// Specify SpecialKey1, SpecialKey2 and SpecialKeyHoldTime for this option.
#define AM_NO_CLEAR			0x00000008
#define AM_NO_SCROLL_BAR	0x00000010  // Valid for AL_CreateList() only.

#define AM_PIX(y) ((y) | 0x80000000)
#define AM_GETPIX(y) ((y) & 0x7fffffff)
#define AM_isPIX(y) ((y) & 0x80000000)

//Menu item
typedef struct {
	int id;
	int ypos;
	int xpos;
	void *menuText;		//Set pAM_EditParam here when showControl is AM_TEXT_EDIT.
	int paletteIndex;
	bool visible;
    bool enabled;
	bool selectable;
	int showControl;
	bool checked;
	int font;					//Optional:Font of this item. If zero, default font is used for this item.
	unsigned short itemOption;				//Optional:Option flag
} AM_MenuItem;
//Difinition of itemOption
#define IS_MULTI_LINE			0x0001 // Only for internal use of the library.
#define IS_MULTI_LINE_START		0x0002 // Only for internal use of the library.
#define IS_MULTI_LINE_END		0x0004 // Only for internal use of the library.

/***********************************************
 * Multi line item
 *  Items of multi line must include AM_MULTI_START, AM_MULTI_MID or AM_MULTI_END.
 *  The first item of multi line must include AM_MULTI_START.
 *  The last item of multi line must include AM_MULTI_END.
 *  Intermidiate item of multi line must include AM_MULTI_MID if exisist.
 *  "visible", "enabled" and "selectable" of AM_MULTI_MID item and AM_MULTI_END item are ignored
 */
#define AM_MULTI_START			(IS_MULTI_LINE | IS_MULTI_LINE_START)
#define AM_MULTI_MID			(IS_MULTI_LINE)
#define AM_MULTI_END			(IS_MULTI_LINE | IS_MULTI_LINE_END)

// Barcode buffer configuration
typedef struct{
	char	*dataBuf;			//(IO) Output buffer for barcode data
	int		dataBufLength;		//(I)  Length of output buffer
	int		outputLength;		//(O)
	int		id;					//(O)
	char 	opticonID;			//(O)
	char 	aimID[4];			//(O)
} AM_BarcodeBuffer, *pAM_BarcodeBuffer;

//Candidate table for ALPHA mode
typedef struct {
	char *listForNum[10];
	char *listForPeriod;
} AM_ShiftCandidateTable, *pAM_ShiftCandidateTable;

//Parameters for AM_TEXT_EDIT control
typedef struct _AM_EditParam{
	int MaxDigits;
	int CursorForeColor;
	int CursorBackColor;
	int ShiftModeForeColor;
	int ShiftModeBackColor;
	int EditOption;
	pAM_ShiftCandidateTable alphaCandidateTable;
	char *Value;
	int ValueBufSize;
} AM_EditParam, *pAM_EditParam;

// Bit flags for AM_EditParam.EditOption
#define AM_EDIT_USE_CLEAR 			0x00000001	// Clear text when CLEAR is pressed
#define AM_EDIT_NUMERIC 			0x00000002	// Numeric characters only (SHIFT_KEY is ignored)
#define AM_EDIT_RIGHT 				0x00000004	// Right aligned (only valid with AM_EDIT_NUMERIC field)
#define AM_EDIT_NO_CURSOR			0x00000008	// No cursor
#define AM_EDIT_NUMERIC_RIGHT		(AM_EDIT_RIGHT|AM_EDIT_NUMERIC|AM_EDIT_NO_CURSOR)

#define AM_EDIT_ALLOW_HEX			0x00000010	// Allowed to switch to HEX input mode by SHIFT_KEY at non numeric field
#define AM_EDIT_DISALLOW_ALPHA		0x00000020	// Disallowed to switch to ALPHA input mode by SHIFT_KEY at non numeric field
#define AM_EDIT_DISALLOW_ALPHA_CAPS	0x00000040	// Disallowed to switch to ALPHA_CAPS input mode by SHIFT_KEY at non numeric field
#define AM_EDIT_SET_NUMERIC			0x00000080	// Set initial shift mode to numeric mode
#define AM_EDIT_SET_ALPHA			0x00000100	// Set initial shift mode to alpha mode
#define AM_EDIT_SET_ALPHA_CAPS		0x00000200	// Set initial shift mode to alpha mode
#define AM_EDIT_SET_HEX				0x00000400	// Set initial shift mode to hex mode

#define AM_EDIT_PASSWORD			0x00000800	// Display '*' (only valid with non numeric field)
#define AM_EDIT_UNDERLINE			0x00001000	// Show underline under text field
#define AM_EDIT_CLEAR_ON_FIRST_CHAR	0x00002000	// Clear text buffer on the first input
#define AM_EDIT_MOVE_CURSOR_BY_Q1Q2	0x00004000	// Move cursor position by Q1 and Q2
#define AM_EDIT_NO_PERIOD			0x00008000	// Ignore period input at non numeric field. (Period is ingnored always at numeric field.)

typedef void * MENU_HANDLE;

MENU_HANDLE AM_CreateMenu(const AM_MenuItem *menuTable, const pAM_Option option);
void AM_ShowMenu(MENU_HANDLE menu, int defaultID);
void AM_StopUpdateScreen(MENU_HANDLE menu);
bool AM_Paint(MENU_HANDLE menu, int id);
bool AM_PaintRange(MENU_HANDLE menu, int IdOfStartLine, int IdOfEndLine);
void AM_ReleaseMenu(MENU_HANDLE menu);
int AM_ExecMenu(MENU_HANDLE menu);
void AM_SetEvent(MENU_HANDLE menu, int event);
bool AM_IsChecked(MENU_HANDLE menu, int id);
bool AM_SetEnabled(MENU_HANDLE menu, int id, bool enable);
bool AM_SetEnabledRange(MENU_HANDLE menu, int IdOfStartLine, int IdOfEndLine, bool enable);
bool AM_IsEnabled(MENU_HANDLE menu, int id);
bool AM_SetVisible(MENU_HANDLE menu, int id, bool visible);
bool AM_SetVisibleRange(MENU_HANDLE menu, int IdOfStartLine, int IdOfEndLine, bool visible);
bool AM_IsVisible(MENU_HANDLE menu, int id);
bool AM_SetSelectable(MENU_HANDLE menu, int id, bool selectable);
bool AM_IsSelectable(MENU_HANDLE menu, int id);
bool AM_SetChecked(MENU_HANDLE menu, int id, bool checked);
bool AM_SetPaletteIndex(MENU_HANDLE menu, int id, int paletteIndex);
int AM_GetPaletteIndex(MENU_HANDLE menu, int id);
int AM_GetSelectedLine(MENU_HANDLE menu);
int AM_GetSelectedLineNumber(MENU_HANDLE menu);
void AM_SelectLine(MENU_HANDLE menu, int id);
bool AM_SetText(MENU_HANDLE menu, int id, char *text);
bool AM_SetTextEx(MENU_HANDLE menu, int id, char *text, bool ClearItem);
char *AM_GetText(MENU_HANDLE menu, int id);
bool AM_SetControlType(MENU_HANDLE menu, int id, int control, bool clearItem);
int AM_GetControlType(MENU_HANDLE menu, int id);
pAM_ShiftCandidateTable AM_GetAlphaCandidateTable(MENU_HANDLE menu, int id);
bool AM_SetEditParamPassword(MENU_HANDLE menu, int id, bool value);
void AM_ConfigBarcodeReader(MENU_HANDLE menu, pAM_BarcodeBuffer pBuffer, char *pOptionCommands);
void AM_EnableBarcodeReader(MENU_HANDLE menu);
void AM_DisableBarcodeReader(MENU_HANDLE menu);

bool AM_SetIdleCallback(MENU_HANDLE menu,
	bool( *IdleCallback)(MENU_HANDLE menu, void *param),
	void *param
);
void AM_RemoveIdleCallback(MENU_HANDLE menu);

char *copyText(char *dst, int dstsize, const char *src, int length, bool padding);

//////////////////////////////////////////////////////////
// List control
//////////////////////////////////////////////////////////
#define AL_MAX_LIST_TEXT_SCREEN 21					//Max char on screen is 21
#define AL_MAX_LIST_TEXT (AL_MAX_LIST_TEXT_SCREEN+3)	//+2 to detect overflow. +1 for null

//List item
typedef struct {
	const char *listText; // This is only for input parameter of AL_AddListItem() and not valid after adding AL_ListItem to AL_ListItemData array.
	int paletteIndex;
	int showControl;
	bool checked;
	int userParam1;	//Optional
	int userParam2;	//Optional
	char userParam3[16]; //Optional
} AL_ListItem;

//List item stored in ListItemData array.
typedef struct {
	AL_ListItem listItem;
	char text[AL_MAX_LIST_TEXT];	//text is copied from AL_ListItem.listText to here when AL_AddListItem() is called.
} AL_ListItemData;

typedef void * LIST_HANDLE;

LIST_HANDLE AL_CreateList(const AM_MenuItem *menuTable, const pAM_Option option, int list_ypos, int list_lines);
bool AL_AddListItem(LIST_HANDLE list, AL_ListItem *item);
bool AL_AddListItemEx(LIST_HANDLE list, const char *listText, int paletteIndex, int showControl, bool checked, int userParam1, int userParam2, char *userParam3);
void AL_SortListItem(LIST_HANDLE list, int( *compare)(const AL_ListItemData *a, const AL_ListItemData *b));
int AL_GetLines(LIST_HANDLE list);
void AL_ReleaseList(LIST_HANDLE list);
void AL_ShowList(LIST_HANDLE list, int startIndex, unsigned int defaultIndex);
void AL_RepaintList(LIST_HANDLE list);
int AL_ExecList(LIST_HANDLE list);

bool AL_IsChecked(LIST_HANDLE list, int index);
bool AL_SetChecked(LIST_HANDLE list, int index, bool checked);
bool AL_SetPaletteIndex(LIST_HANDLE list, int index, int paletteIndex);
int AL_GetSelectedIndex(LIST_HANDLE list);
void AL_SelectIndex(LIST_HANDLE list, int index);
int AL_GetStartIndex(LIST_HANDLE list);
bool AL_GetListItemData(LIST_HANDLE list, int index,  AL_ListItemData *listItemData);
bool AL_SetText(LIST_HANDLE list, int index, char *text);
bool AL_SetUserParam1(LIST_HANDLE list, int index, int param);
bool AL_SetUserParam2(LIST_HANDLE list, int index, int param);
bool AL_SetUserParam3(LIST_HANDLE list, int index, char *param);
MENU_HANDLE AL_GetMenuHandle(LIST_HANDLE list);

#endif /* INCLUDE_ADVENCEDMENU_H_ */
