//
// anyRemote
// a wi-fi or bluetooth remote for your PC.
//
// Copyright (C) 2006-2016 Mikhail Fedotov <anyremote@mail.ru>
//
// 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 3 of the License, or
// (at your option) 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//

#ifndef _PARSE_H_
#define _PARSE_H_ 1

#include "common.h"
#include "list.h"
#include <sys/types.h>
#include <unistd.h>

#define CFGFILE 	"/.anyremote.cfg"

/* Constants */
#define MAXARGLEN   	256
#define MAXNAMELEN   	512
#define MAXCMDLEN   	1024

#define KEYS_SECTION_STR     "[Keys]"
#define PROTOCOL_SECTION_STR "[Protocol]"
#define MODE_END_STR         "[ModeEnd]"
#define MODE_STR    	     "[Mode]"
#define SECTION_END_STR      "[End]"

// Some AT stuff
// \r will be added before send
#define DEF_AT_CMER_ON_DEFAULT   "AT+CMER=3,2,0,0,0" 	// Default, valid for SE and Siemens S55 phones
#define DEF_AT_CMER_OFF_DEFAULT  "AT+CMER=0,0,0,0,0"
#define DEF_AT_CMER_ON_SE        "AT+CMER=3,2,0,0,0" 	// SE, same as default
#define DEF_AT_CMER_OFF_SE       "AT+CMER=0,0,0,0,0"
#define DEF_AT_CMER_ON_MOTOROLA  "AT+CMER=3,1,0,0,0" 	// Motorola phones	
#define DEF_AT_CMER_OFF_MOTOROLA "AT+CMER=0,0,0,0,0"
#define DEF_AT_CMER_ON_SAGEM     "AT+CMER=2,1,0,0,0" 	// Sagem phones
#define DEF_AT_CMER_OFF_SAGEM    "AT+CMER=0,0,0,0,0"
#define DEF_AT_CMER_ON_SIEMENS   "AT+CMER=3,2,0,0,0" 	// Siemens phones, same as default
#define DEF_AT_CMER_OFF_SIEMENS  "AT+CMER=0,0,0,0,0"

#define DEF_AT_CGMI     "AT+CGMI"
#define DEF_AT_CLCC     "AT+CLCC"		// ? will be added later (will try both variants)
#define DEF_AT_CSCS     "AT+CSCS="
#define DEF_AT_CKPD 	"AT+CKPD="
#define DEF_AT_CLIP 	"AT+CLIP=1"
#define DEF_AT_CMEC 	"AT+CMEC=2"		// used by Siemens to made AT+CKPD works
#define DEF_CKEV 	"+CKEV:"
#define DEF_CLCC 	"+CLCC:"
#define DEF_RING 	"RING"			// It could be RING or +CRING (depends on AT+CRC)
#define DEF_MSG 	"Msg:"			// Used by Java Client
#define DEF_CLDEBUG "Msg:_DEBUG_("	// Used by Java Client
#define DEF_CLPING  "Msg:Ping"	    // Used by Java Client

#define CMER_ON  	1
#define CMER_OFF  	2

#define SAME 	    	99
#define PAUSE_STR   	"PAUSE"

enum EventID {
    ID_EVT_INIT = 0,
    ID_EVT_EXIT,
    ID_EVT_CONNECT,
    ID_EVT_DISCONNECT,
    ID_EVT_MAX
};

#define EVT_INIT     	"(Init)"
#define EVT_EXIT        "(Exit)"
#define EVT_CONNECT     "(Connect)"
#define EVT_DISCONNECT  "(Disconnect)"
#define EVT_ENTRMODE	"(EnterMode)"
#define EVT_EXITMODE    "(ExitMode)"

#define ID_UNKNOWN    	-1

enum CommandID {
    ID_EXIT = 0,  
    ID_EXEC,      
    ID_SENDCKPD,  
    ID_SET,       
    ID_EXECSET,   
    ID_TIMER,     
    ID_SEND,      
    ID_EXECSEND,  
    ID_MACRO,     
    ID_LOAD,      
    ID_INCLUDE,   
    ID_GET,       
    ID_MAKE,      
    ID_EMU,       
    ID_DBUS,      
    ID_CMD_MAX      
};

#define CMD_EXIT    	"Exit"
#define CMD_EXEC        "Exec"
#define CMD_SENDCKPD    "SendCKPD"		// AT mode only
#define CMD_SET         "Set"			// Server mode only
#define CMD_EXECSET     "ExecAndSet"		// Server mode only
#define CMD_TIMER       "Timer"
#define CMD_SEND        "Send"  		// Server mode only, used for Bemused-server emulation
#define CMD_EXECSEND    "ExecAndSend"		// Server mode only, used for Bemused-server emulation
#define CMD_MACRO       "Macro"
#define CMD_LOAD        "Load"
#define CMD_INCLUDE     "Include"
#define CMD_GET         "Get"			// Server mode only	 
#define CMD_MAKE        "Make"
#define CMD_EMU         "Emulate"
#define CMD_DBUS        "Dbus"

#define SET_BG          "bg"
#define SET_CAPTION     "caption"
#define SET_PARAM       "parameter"
#define SET_EFIELD      "editfield"
#define SET_FG          "fg"
#define SET_FMGR        "filemanager"
#define SET_FONT        "font"
#define SET_FSCREEN     "fullscreen"
#define SET_ICONS       "icons"
#define SET_HINTS       "hints"
#define SET_LIST        "list"
#define SET_ILIST       "iconlist"
#define SET_MENU        "menu"
#define SET_REPAINT     "repaint"
#define SET_SKIN        "skin"	// obsolete
#define SET_LAYOUT      "layout"
#define SET_STATUS      "status"
#define SET_TEXT        "text"
#define SET_TITLE       "title"
#define SET_VIBRATE     "vibrate"
#define SET_VOLUME      "volume"
#define SET_IMAGE       "image"
#define SET_COVER       "cover"
#define SET_POPUP       "popup"
#define SET_DISCONN     "disconnect"

enum CommandSetID {
    ID_SET_BG = 0,
    ID_SET_CAPTION,
    ID_SET_PARAM,
    ID_SET_EFIELD,
    ID_SET_FG,
    ID_SET_FMGR,
    ID_SET_FONT,
    ID_SET_FSCREEN,
    ID_SET_ICONS,
    ID_SET_HINTS,
    ID_SET_LIST,
    ID_SET_ILIST,
    ID_SET_MENU,
    ID_SET_REPAINT,
    ID_SET_LAYOUT,
    ID_SET_STATUS,
    ID_SET_TEXT,
    ID_SET_TITLE,
    ID_SET_VIBRATE,
    ID_SET_VOLUME,
    ID_SET_IMAGE,
    ID_SET_COVER, 
    ID_SET_POPUP,
    ID_SET_DISCONN,
    ID_SET_MAX
};

#define MAKE_DISCONN    "disconnect"
#define MAKE_MODE       "mode"
#define MAKE_ALARM      "alarm"
#define MAKE_FLUSH      "flush"
#define MAKE_STOP       "stop"
#define MAKE_REMOTE     "remote"
#define MAKE_VAR        "var"
#define MAKE_EXIT       "exit"
#define MAKE_NONE       "none"

enum CommandMakeID {
    ID_MAKE_DISCONN = 0,
    ID_MAKE_MODE,
    ID_MAKE_ALARM,
    ID_MAKE_FLUSH,
    ID_MAKE_STOP,
    ID_MAKE_REMOTE,
    ID_MAKE_VAR,
    ID_MAKE_EXIT,
    ID_MAKE_NONE,
    ID_MAKE_MAX
};

#define GET_SCREENSIZE  "screen_size"
#define GET_COVERSIZE   "cover_size"
#define GET_ICONSIZE    "icon_size"
#define GET_ICONPADDING "icon_padding"
#define GET_MODEL       "model"
#define GET_VERSION     "version"
#define GET_CURSOR      "cursor"
#define GET_PING        "ping"
#define GET_PASSWORD    "password"
#define GET_ISEXISTS    "is_exists"

enum CommandGetID {
    ID_GET_SCREENSIZE = 0, 
    ID_GET_COVERSIZE,  
    ID_GET_ICONSIZE,  
    ID_GET_ICONPADDING,
    ID_GET_MODEL,     
    ID_GET_VERSION,    
    ID_GET_CURSOR,     
    ID_GET_PING,       
    ID_GET_PASSWORD,   
    ID_GET_ISEXISTS,
    ID_GET_MAX
};

enum CommandEventID {
    ID_EVENT_FRONTEND,       
    ID_EVENT_INIT,     
    ID_EVENT_DISCONNECT,
    ID_EVENT_EXIT,     
};

#define TIMER_CANCEL   "cancel"
#define TIMER_PAUSE    "pause"
#define TIMER_RESET    "reset"
#define TIMER_RESTART  "restart"
#define TIMER_CONTINUE "continue"

enum CommandTimerID {
    ID_TIMER_CREATE = 0,
    ID_TIMER_CANCEL,
    ID_TIMER_PAUSE,
    ID_TIMER_RESET,
    ID_TIMER_RESTART,
    ID_TIMER_CONTINUE,
    ID_TIMER_MAX
};

#define UPLOAD_ICON    "image,icon"
#define UPLOAD_PIX     "image,window"
#define UPLOAD_COVER   "image,cover"
#define UPLOAD_COVER_DATA "cover,noname"

#define STR_MOTOROLA	"Motorola"
#define STR_SE   	    "Sony Ericsson"
#define STR_SAGEM	    "SAGEM"
#define STR_SIEMENS   	"SIEMENS"

#define MODEL_DEFAULT	0
#define MODEL_SE	    1
#define MODEL_MOTOROLA	2
#define MODEL_SAGEM	    3
#define MODEL_SIEMENS	4

#define FLAG_EXACT	-1 // All non-negative values could be indexes in the list
#define FLAG_MULTIKEY	-2
#define FLAG_PARAMETR	 1
#define FLAG_UNDEF	-3

typedef struct Ci {
    int        type;
    int        subtype;
    char       *descr;
    char       *exec;
} cmdItem;

typedef struct Tk {
    char        *key;
    SingleList  *commands;  // list of cmdItem*
    struct Tk   *next;
} type_key;

typedef struct Cp {
    char       index[6];
    char       value[MAXARGLEN];
} cmdParams;

typedef struct {
    int   model;
    int   frontEnd;
    uid_t   uid;
    gid_t   gid;
} CONF;

// Exported functions definitions

const char* id2Cmd      (int cmdId);
void  init_cfg_dir      (char *path);
int   init_cfg          (char *path);
void  freeRegexps       (void);
int   parse_opts        (int argc, char *argv[]);
int   storeCmds         (SingleList** commands, const char *value);
int   load_cfg		(const char *mfile, int isInit);
int   cmdSet2id         (const char *what_to_set);

#endif
