
#include "../config.h"

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

#include "img_format.h"
#include "mp_image.h"

#include "../m_option.h"
#include "../m_struct.h"
#include "../asxparser.h"
#include "menu.h"
#include "menu_list.h"

#include "../libvo/font_load.h"

#include "../input/input.h"
#include "../version.h"

struct list_entry_s {
  struct list_entry p;

  char* ok;
  char* cancel;
};

struct menu_priv_s {
  menu_list_priv_t p;
};

static struct menu_priv_s cfg_dflt = {
  MENU_LIST_PRIV_DFLT
};

static m_option_t cfg_fields[] = {
  MENU_LIST_PRIV_FIELDS,
  { "title",M_ST_OFF(struct menu_priv_s,p.title), CONF_TYPE_STRING, 0, 0, 0, NULL },
  { NULL, NULL, NULL, 0,0,0,NULL }
};

#define mpriv (menu->priv)

#include "../mp_msg.h"
#define AUTOREPLAY_STR	"autoreplay"
#define SHTIMER_STR	"shutdown_timer"
#define BATTERY_STR	"show_battery"
#define OFFSCR_STR	"off_screen"
#define GOSONG_STR	"gosong"
char titlestr[64];
#include <string.h>
char itemtext[128];
char curtitle[128];

static char *ParseString1(char *src) // convert [0 - test] --> [0-test]
{
    static char result[128];
    char *ptr;
    char *temp;
    printf("ParseString1 [%s]\n",src);
    result[0] = 0;
    temp = strdup(src);
    ptr = strstr(temp," - ");
    if (ptr) {
        char *ptr1 = ptr + 3;
        *ptr = 0;
        sprintf(result,"%s-%s",temp,ptr1);
    } else {
        sprintf(result,ptr);
    }
    free(temp);
    printf("ParseString1 return [%s]\n",result);
    return result;
}

static char *MergeString(char *name, char *title)
{
    char *r1 = NULL;
    
    printf("*MergeString [%s] [%s]\n",name,title);
    char *temp = strdup(title);
    char *ptr = strchr(temp,'(');
    if (ptr) {
        char *r2;
        *(ptr+1) = 0;
        r2 = ParseString1(name);
        r1 = (char *) malloc(strlen(temp) + strlen(r2) + 3);
        if (r1) {
            sprintf(r1,"%s%s)",temp,r2);            
        }
    }
    free(temp);
    return r1;        
}

#if 0
static char *myconv(char *myname,char *title)
{
	static char res[64];
	char r1[64];
	char r2[64];
	char src[64];
	char *ptr,*ptr2;
	strncpy(r2,title,63);
	strncpy(src,myname,63);

	if (strcmp(src,"No Subtitle")) {
		ptr = src;
		ptr2 = r1;	
		while (*ptr) {
			if (*ptr != ' ') {
				*ptr2 = *ptr;
				ptr2++;
			}
			ptr++;
		}
		*ptr2 = 0;
	} else {
		strncpy(r1,src,63);
	}

	ptr = strchr(r2,'(');
	*ptr = 0;	
	
	sprintf(res,"%s(%s)",r2,r1);
	return res;
} 
#endif

void MyProcessCommand(menu_t *menu, mp_cmd_t* c)
{
	char msgstr[64];
	char *oldstr;

	if (strcmp(c->name,"dvdchapter") && 
		strcmp(c->name,"dvdsub") &&
		strcmp(c->name,"dvdaudio") &&
		strcmp(c->name,"dvdangle") &&
		strcmp(c->name,"dvdtitle") &&
		strcmp(c->name,"autoreplay") &&
		strcmp(c->name,"shutdown_timer") &&
		strcmp(c->name,"show_battery") &&
		strcmp(c->name,"selecthdd") &&
		strcmp(c->name,"gosong") 
		) { 
		mp_input_queue_cmd(c);
	}
    if (strcmp(c->name,AUTOREPLAY_STR) == 0) {
		avamax_var->my_autoreplay = c->args[0].v.i;
		sprintf(titlestr,"%s [%s]",
			avamax_var->lang_str[2],
			avamax_var->lang_str[(avamax_var->my_autoreplay == 1) ? 0 : 1]);
		sprintf(msgstr,"MENU SETTING " AUTOREPLAY_STR " %d\n", 
			avamax_var->my_autoreplay);
		oldstr = mpriv->p.title;
        mpriv->p.title = strdup(titlestr);
		free(oldstr);
    } else if (strcmp(c->name,SHTIMER_STR) == 0) {
        avamax_var->my_shtimer = c->args[0].v.i;
		if (avamax_var->my_shtimer == 0) {
			sprintf(titlestr,"%s [%s]",
				avamax_var->lang_str[3],
				avamax_var->lang_str[1]);
		} else {
        	sprintf(titlestr,"%s [%d]", 
				avamax_var->lang_str[3],
				avamax_var->my_shtimer);
		}
		sprintf(msgstr,"MENU SETTING " SHTIMER_STR " %d\n", 
			avamax_var->my_shtimer);
		oldstr = mpriv->p.title;
        mpriv->p.title = strdup(titlestr);
		free(oldstr);
	} else if (strcmp(c->name,BATTERY_STR) == 0) {
		avamax_var->my_shbattery = c->args[0].v.i;
		sprintf(titlestr,"%s [%s]",
			avamax_var->lang_str[4],
			avamax_var->lang_str[(avamax_var->my_shbattery) ? 0 : 1]);
		sprintf(msgstr,"MENU SETTING " BATTERY_STR " %d\n", avamax_var->my_shbattery);
		oldstr = mpriv->p.title;
        mpriv->p.title = strdup(titlestr);
		free(oldstr);
    } else if (strcmp(c->name,OFFSCR_STR) == 0) {
        avamax_var->my_off_screen = c->args[0].v.i;
		if (avamax_var->my_off_screen == 0)
			strcpy(titlestr,"LED Off Timer [Off]");
		else
        	sprintf(titlestr,"LED Off Timer [%d]", avamax_var->my_off_screen);
		sprintf(msgstr,"MENU SETTING " OFFSCR_STR " %d\n", 
			avamax_var->my_off_screen);
		oldstr = mpriv->p.title;
        mpriv->p.title = strdup(titlestr);
		free(oldstr);
	} 
	else if ((strcmp(c->name,"dvdaudio") == 0) ||  
			(strcmp(c->name,"dvdsub") == 0) 
		) {
		char *temp = MergeString(itemtext,curtitle);
		if (temp) {
		    strcpy(titlestr,temp);
		    free(temp);
		}
		msgstr[0] = 0;
	}
	else if (strcmp(c->name,"selecthdd") == 0) {
        titlestr[0] = 0;
        sprintf(msgstr,"SELECTHDD %s",c->args[0].v.s);
    }
    else {
		msgstr[0] = 0;
		titlestr[0] = 0;
	}
	if (strlen(msgstr) > 0) {
		My_SendMessage(msgstr,150);
	} else if (strcmp(c->name,"menu") && strcmp(c->name,"set_menu")) {
		char temp[128];
		sprintf(temp,"MENU COMMAND %s %d",c->name,c->args[0].v.i);
        My_SendMessage(temp,150);
    }
}

static void read_cmd(menu_t* menu,int cmd) {

    strcpy(itemtext,mpriv->p.current->p.txt);
    strcpy(curtitle,mpriv->p.title);

  switch(cmd) {
  case MENU_CMD_OK: {
    if(mpriv->p.current->ok) {
      mp_cmd_t* c = mp_input_parse_cmd(mpriv->p.current->ok);
      if(c)
      {
		MyProcessCommand(menu, c);
		if (strlen(titlestr) > 0) {
       		menu_change_title(c->name,titlestr);
    	}
      }
	}

   } break;
  case MENU_CMD_CANCEL:
    if(mpriv->p.current->cancel) {
      mp_cmd_t* c = mp_input_parse_cmd(mpriv->p.current->cancel);
      if(c)
	mp_input_queue_cmd(c);
      break;
    }
  default:
    menu_list_read_cmd(menu,cmd);
  }
}

static void read_key(menu_t* menu,int c){
  menu_list_read_key(menu,c,0);
}

static void free_entry(list_entry_t* entry) {
  if(entry->ok)
    free(entry->ok);
  if(entry->cancel)
    free(entry->cancel);
  free(entry->p.txt);
  free(entry);
}

static void close(menu_t* menu) {
  menu_list_uninit(menu,free_entry);
}

extern char *menu_find_name_by_title(char *ttt);

static int parse_args(menu_t* menu,char* args) {
  char *element,*body, **attribs, *name, *ok, *cancel;
  list_entry_t* m = NULL;
  int r;
  ASX_Parser_t* parser = asx_parser_new();
  
  //char *MNAME = strdup(menu_find_name_by_title(menu->priv->p.title));
  char MatchName_sub[32];
  char MatchName_aid[32];
  
  sprintf(MatchName_sub,"dvdsub %d",avamax_var->my_new_subid);
  sprintf(MatchName_aid,"dvdaudio %d",avamax_var->my_new_aid);
        
  while(1) {
    r = asx_get_element(parser,&args,&element,&body,&attribs);
    if(r < 0) {
      printf("Syntax error at line %d\n",parser->line);
      asx_parser_free(parser);
      return -1;
    } else if(r == 0) {      
      asx_parser_free(parser);
      if(!m)
	printf("No entry found in the menu definition\n");
      return m ? 1 : 0;
    }
    // Has it a name ?
    name = asx_get_attrib("name",attribs);
    if(!name) {
      printf("List menu entry definitions need a name (line %d)\n",parser->line);
      free(element);
      if(body) free(body);
      asx_free_attribs(attribs);
      continue;
    }
    ok = asx_get_attrib("ok",attribs);
    cancel = asx_get_attrib("cancel",attribs);
    m = calloc(1,sizeof(struct list_entry_s));
    m->p.txt = name;
    m->ok = ok;
    m->cancel = cancel;
    menu_list_add_entry(menu,m);    
	if (ok) {
    if (strcmp(ok,MatchName_sub) == 0) {
        char *newstr = MergeString(name,menu->priv->p.title);
        if (newstr) {        
            free(menu->priv->p.title);
            menu->priv->p.title = newstr;
        }
        MatchName_sub[0] = 0;
        avamax_var->my_new_subid = -100;
    } else if ((strcmp(ok,MatchName_aid) == 0)) {
        char *newstr = MergeString(name,menu->priv->p.title);
        if (newstr) {        
            free(menu->priv->p.title);
            menu->priv->p.title = newstr;
        }
        MatchName_aid[0] = 0;
        avamax_var->my_new_aid = -100;
    }
	}

    free(element);
    if(body) free(body);
    asx_free_attribs(attribs);
  }
	printf("Parse_args end.....\n");
  //free(MNAME);
}

static int open(menu_t* menu, char* args) {
  menu->draw = menu_list_draw;
  menu->read_cmd = read_cmd;
  menu->read_key = read_key;
  menu->close = close;

  if(!args) {
    printf("List menu need an argument\n");
    return 0;
  }
 
  menu_list_init(menu);
  if(!parse_args(menu,args))
    return 0;

  return 1;
}

const menu_info_t menu_info_cmdlist = {
  "Command list menu",
  "cmdlist",
  "Albeu",
  "",
  {
    "cmdlist_cfg",
    sizeof(struct menu_priv_s),
    &cfg_dflt,
    cfg_fields
  },
  open
};
