/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id: RockCalendar.c
 *
 * by Ben Basha (Paprica)
 *
 * All files in this archive are subject to the GNU General Public License.
 * See the file COPYING in the source tree root for full license agreement.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
 
#include "plugin.h"
#include "configfile.h"
#include "xlcd.h"

#ifdef HAVE_LCD_COLOR

PLUGIN_HEADER

static struct plugin_api* rb;

#if CONFIG_KEYPAD == IRIVER_H300_PAD
 
#define UP     BUTTON_UP
#define DOWN   BUTTON_DOWN
#define LEFT   BUTTON_LEFT
#define RIGHT  BUTTON_RIGHT
#define SELECT BUTTON_SELECT
#define CANCEL BUTTON_OFF
#define NEXT_MONTH BUTTON_REC
#define PREV_MONTH BUTTON_ON
#define MENU BUTTON_MODE

#elif CONFIG_KEYPAD == IPOD_4G_PAD

#define UP     BUTTON_MENU
#define DOWN   BUTTON_PLAY
#define LEFT   LEFT
#define RIGHT  RIGHT
#define SELECT SELECT
#define CANCEL (BUTTON_PLAY | BUTTON_REPEAT)
#define NEXT_MONTH BUTTON_SCROLL_FWD
#define PREV_MONTH BUTTON_SCROLL_BACK
#define MENU (SELECT | BUTTON_REPEAT)

#endif

/* ################################################################ 
   ##############             Bitmaps                ##############
   ################################################################ */
#define NOTE_WIDTH 12
#define NOTE_HEIGHT 13
extern const fb_data rockcalendar_note[];

#define BALLOONS_WIDTH 10
#define BALLOONS_HEIGHT 15
extern const fb_data rockcalendar_balloons[];

#define HOUSE_WIDTH 15
#define HOUSE_HEIGHT 14
extern const fb_data rockcalendar_house[];

#define KEY_WIDTH 220
#define KEY_HEIGHT 81
#define KEY_YPOS LCD_HEIGHT-KEY_HEIGHT
extern const fb_data rockcalendar_keyboard[];
extern const fb_data rockcalendar_disable_keyboard[];

/* ################################################################ 
   ##############              KeyBoard              ##############
   ################################################################ 
           The keyboard bitmap and code takes from RockWord
*/
   
#define KEYBOARD_SIZE 57
enum keys {
     KEY_BACK,
     KEY_CR,
     KEY_CTRL,
     KEY_HOME,
     KEY_END,
     KEY_DEL,
     KEY_UP,
     KEY_LEFT,
     KEY_DOWN,
     KEY_RIGHT,
     KEYS_ACTIONS,
};

static short key_coords[KEYBOARD_SIZE][4]=
/* 1st line - 0 */
{{0,0,12}, /* ` */ {11,0,17}, /* 1 */ {27,0,17}, /* 2 */ {43,0,17}, /* 3 */ {59,0,17}, /* 4 */ {75,0,17}, /* 5 */ {91,0,17}, /* 6 */
 {107,0,17}, /* 7 */ {123,0,17}, /* 8 */ {139,0,17}, /* 9 */ {155,0,17}, /* 0 */ {171,0,17}, /* - */ {187,0,17}, /* = */ {203,0,17}, /* <-*/
/* 2nd line - 16 */
 {20,16,17}, /* q */ {36,16,17}, /* w */ {52,16,17}, /* e */ {68,16,17}, /* r */ {84,16,17}, /* t */ {100,16,17}, /* y */ 
 {116,16,17}, /* u */ {132,16,17}, /* i */ {148,16,17}, /* o */ {164,16,17}, /* p */ {180,16,17}, /* [ */ {196,16,17}, /* ] */ 
/* 3rd line - 32 */
 {25,32,17}, /* a */ {41,32,17}, /* s */ {57,32,17}, /* d */ {73,32,17}, /* f */ {89,32,17}, /* g */ {105,32,17}, /* h */ 
 {121,32,17}, /* j */ {137,32,17}, /* k */ {153,32,17}, /* l */ {169,32,17}, /* ; */ {185,32,17}, /* ' */ {201,32,19}, /* Cr*/
/* 4th line - 48 */
 {27,48,17}, /* z */ {43,48,17}, /* x */ {59,48,17}, /* c */ {75,48,17}, /* v */ {91,48,17}, /* b */ {107,48,17}, /* n */
 {123,48,17}, /* m */ {139,48,17}, /* , */ {155,48,17}, /* . */ {171,48,17}, /* / */ {187,48,17}, /* ^ */ {203,48,17}, /* \ */
/* 5th line - 64 */
 {38,64,84}, /*   */ {121,64,21}, /* Hm*/ {141,64,17}, /* En*/ {157,64,15}, /* dl*/
 {171,64,17}, /* < */ {187,64,17}, /* V */ {203,64,17}  /* > */ } ;
 
unsigned char key_chars[KEYBOARD_SIZE]={
/* English */
 '`','1','2','3','4','5','6','7','8','9','0','-','=',KEY_BACK,
 'q','w','e','r','t','y','u','i','o','p','[',']', 
 'a','s','d','f','g','h','j','k','l',';','\'',KEY_CR,
 'z','x','c','v','b','n','m',',','.','/',KEY_UP,'\\',
 ' ',KEY_HOME,KEY_END,KEY_DEL,KEY_LEFT,KEY_DOWN,KEY_RIGHT
 };


/* ################################################################ 
   ##############          Global variables          ##############
   ################################################################ */
   
int first_week_day=0; /* default 0=sunday */
int iriver_fw=0; /* use it when the date is set in iriver orginal firmware to dd/mm/1999 for the year 2006 */
static struct configdata config[2] = {
   { TYPE_INT, 0, 1, &first_week_day, "first_week_day", NULL, NULL },
   { TYPE_INT, 0, 1, &iriver_fw, "iriver_fw", NULL, NULL }
};


static int days_in_month[2][12] = {
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

static char month_name[12][10] = {
       "January",
       "February",
       "March",
       "April",
       "May",
       "June",
       "July",
       "August",
       "September",
       "October",
       "November",
       "December",
};

static char calen_days[7][4] ={ 
       "Sun",
       "Mon",
       "Tue",
       "Wed",
       "Thu",
       "Fri",
       "Sat",
}; 
              
#define MESSAGE_LENGTH 30
#define MESSAGE_LINES 8   
           
enum notes_types {
     NOTE,
     FREE_DAY,
     BIRTHDAY,
     HOLIDAY,
     MAX_NOTESTYPES
};

static char type_name[MAX_NOTESTYPES][10] = {
       "Note",
       "Free Day",
       "Birthday",
       "Holiday",
};
     
enum addmenuitems {
     ADD_MENU_DELETE,
     ADD_MENU_EDIT,
     ADD_MENU_YEAR,
     ADD_MENU_TYPE,
     ADD_MENU_DONE,
     ADD_MENU_ITEMS
};

enum daymenuitems {
     DM_ADD,
     DM_VIEW,
     DM_DELETE,
     DM_CANCEL,
     DM_ITEMS
};

enum _menu {
    MENU_1F_WIDTH,
    MENU_1F_HEIGHT,
    MENU_1F_XPOS,
    MENU_1F_YPOS,
    MENU_2F_WIDTH,
    MENU_2F_HEIGHT,
    MENU_2F_XPOS,
    MENU_2F_YPOS,    
};

enum mainmenuitems {
     MM_FIRST,
     MM_IRIVER,
     MM_QUITM,
     MM_QUIT,
     MM_ITEMS
};

enum _menus {
    DAY_MENU_VIEW,
    DAY_MENU_ADD,
    ADD_MENU,
    VIEW_MENU,
    MAIN_MENU,
    MENUS_NUMBER,
};

static int menus[MENUS_NUMBER][8]={
       { 84 , 13, 68, 63,  84, 44, 68, 75  },
       { 84 , 13, 68, 63,  84, 44, 68, 75  },
       { 120, 13, 50, 45, 120, 54, 50, 57  },
       { 120, 13, 50, 95, 120, 54, 50, 107 },
       { 145, 13, 37, 53, 145, 44, 37, 65  },
};

static char menu_items[MENUS_NUMBER][5][16]=
{
       { "Add New", "View"          , "Delete", "Cancel", ""     },
       { "Add New", "View"          , "Delete", "Cancel", ""     },
       { "Delete" , "Edit Message"  , "Year:" , "Type:" , "Done" },
       { "Delete" , "Edit Message"  , "Year:" , "Type:" , "Done" },
       { "First Week Day:" , "iRiver FW Date:"  , "Quit Menu" , "Quit Calendar" , "" },
};

#define ADD_MENU_1F_WIDTH 120
#define ADD_MENU_1F_HEIGHT 13
#define ADD_MENU_1F_XPOS 50
#define ADD_MENU_1F_YPOS 45
#define ADD_MENU_2F_WIDTH 120
#define ADD_MENU_2F_XPOS 50
#define ADD_MENU_2F_YPOS 57

#define MENU_1F_COLOR LCD_RGBPACK(0, 70, 157)
#define MENU_2F_COLOR LCD_RGBPACK(0, 83, 187)

#define MONTH_NAME_YPOS 9
#define LEFTMARGIN 8
#define RIGHTMARGIN 8
#define TOPMARGIN 35
#define BOTTOMMARGIN 2
#define SQU_WIDTH 28
#define SQU_HEIGHT 22

#define VIEW_NOTE_MODE 0
#define ADD_NOTE_MODE 1

#define NOTES_FILE PLUGIN_DIR "/cal.da"


struct _note {
    int day;
    int month;
    int year;  
    int type;
    unsigned char message[MESSAGE_LINES][MESSAGE_LENGTH];
};

struct _keyboard {
    int selection;
	int font_width, font_height;
	int currow, curcol;
};

struct calendar {
    int calen[6][7];
    int first_day,last_day;     
    int notes_count;
    int year;  /* the current year */
    int month; /* the current month */
    int row, col; /* the cursor of the calendar */
    struct _note note[200];
};

#define TEXT_YPOS 25
#define TEXT_XPOS 4
#define TEXT_FRAME_XPOS 1
#define TEXT_FRAME_YPOS 14
#define TEXT_FRAME_WIDTH 218
#define TEXT_FRAME_HEIGHT 78

#define UNUSED_TEXT_COLOR LCD_RGBPACK(188,188,188)


static struct calendar cl;
    
/* ################################################################ 
   ##############   Read the notes from the file     ##############
   ################################################################ */

void read_notes(void) 
{

     char buf[MAX_PATH];
     char t[2];
     char dm[3];
     char y[4];
     int fd,i;
     char *pos;
     char *ptr;
     
     rb->splash(0,true,"Loading Data...");
     
     fd = rb->open(NOTES_FILE, O_RDONLY);
     cl.notes_count=0;
     if (fd > -1) {
             rb->lseek(fd, 0, SEEK_SET);
         while (true){
             if (rb->read(fd, t,1) == 1)
                cl.note[cl.notes_count].type=rb->atoi(&t[0]);
             else
                cl.note[cl.notes_count].type=0;
             
             if (rb->read(fd, dm, 2) == 2)
                 cl.note[cl.notes_count].day=rb->atoi(&dm[0]);
             else
                 cl.note[cl.notes_count].day=0;
             
             if (rb->read(fd, dm, 2) == 2)
                 cl.note[cl.notes_count].month=rb->atoi(&dm[0]);
             else
                 cl.note[cl.notes_count].month=0;
             
             if (rb->read(fd, y, 3) == 3)
                cl.note[cl.notes_count].year=rb->atoi(&y[0]);
             else
                cl.note[cl.notes_count].year=0;
             
             rb->read(fd, buf,1);

             if (cl.note[cl.notes_count].day==0 &&
                 cl.note[cl.notes_count].month==0 &&
                 cl.note[cl.notes_count].year==0)
                     break;

             rb->read_line(fd, buf, MAX_PATH);
             ptr= buf;
             pos = rb->strchr(ptr, '|');
             i=0;
             while (pos!=NULL) {
                      if (pos-ptr+1<MESSAGE_LENGTH)
                          rb->memcpy(cl.note[cl.notes_count].message[i],ptr, pos-ptr);
                      else
                          rb->memcpy(cl.note[cl.notes_count].message[i],ptr, MESSAGE_LENGTH);
                      ptr = pos+1;
                      pos = rb->strchr(ptr, '|');
                      i++;
             }            
             
             cl.notes_count++;
         }
     }
     rb->close(fd);
     

     
     configfile_init(rb);
     configfile_load("cal.cfg", config, 2, 0);         

}   
   
/* ################################################################ 
   ##############      Save the notes to file        ##############
   ################################################################ */
   
void save_notes (void)
{
     int fd,i,j;
     char str[MESSAGE_LENGTH];
     
     rb->splash(0,true,"Saving notes...");
     fd=rb->creat(NOTES_FILE,O_WRONLY);
     for(i=0;i<cl.notes_count;i++){
          if (cl.note[i].day>0) {
             rb->fdprintf(fd, "%1d%02d%02d%03d:", cl.note[i].type, cl.note[i].day, 
                          cl.note[i].month, cl.note[i].year);
             for (j=0;j<MESSAGE_LINES;j++)
                if (cl.note[i].message[j][0]!='\0') {
                    rb->snprintf(str, MESSAGE_LENGTH, "%s", cl.note[i].message[j]);
                    rb->fdprintf(fd, "%s|", str);
                }
          }
          rb->fdprintf(fd, "\n"); 
     }   
     rb->close(fd);
     
     configfile_save("cal.cfg", config, 2, 0);
}                          

/* ################################################################ 
   ##############  initialization of the calendar    ##############
   ################################################################ */
   
void calen_init(void)
{
        int x,i,month_day;      

        month_day=0;        
        for (i=0;i<6;i++) {
            for (x=0;x<7;x++) {           
                 if((i==0 && x< cl.first_day) || (month_day >= days_in_month[cl.year%4==0?1:0][cl.month]))
                     cl.calen[i][x]=0; 
                 else {
                     cl.calen[i][x]=++month_day;
                     cl.last_day=x;
                 }
            }
        } 
}      

/* ################################################################ 
   ##############        Keyboard Functions          ##############
   ################################################################ */
   
static void inv_keysel(struct _keyboard kb, bool update)
{	
	rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
	rb->lcd_fillrect(key_coords[kb.selection][0], KEY_YPOS+key_coords[kb.selection][1], key_coords[kb.selection][2], 17);
	rb->lcd_set_drawmode(DRMODE_SOLID);
	if (update) rb->lcd_update_rect(0, KEY_YPOS, KEY_WIDTH, KEY_HEIGHT);
}

static void inv_cursor(struct _keyboard kb, bool update)
{	
    rb->lcd_set_foreground(LCD_BLACK);
	rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
	/* cross painting */
	rb->lcd_fillrect(TEXT_XPOS+kb.curcol*kb.font_width, TEXT_YPOS+2+kb.currow*kb.font_height, kb.font_width, kb.font_height);
	rb->lcd_set_drawmode(DRMODE_SOLID);
	if (update) rb->lcd_update();
}

void keyboard_bitmap(bool disable)
{
     if (disable)
         rb->lcd_bitmap(rockcalendar_disable_keyboard, 0, LCD_HEIGHT - KEY_HEIGHT, KEY_WIDTH, KEY_HEIGHT);
     else
         rb->lcd_bitmap(rockcalendar_keyboard, 0, LCD_HEIGHT - KEY_HEIGHT, KEY_WIDTH, KEY_HEIGHT);
}    
     
static void keyboard_loop(int note_num)
{	
    int button;
    bool done=false;
    char temp[2];
    struct _keyboard kb;
    
    rb->lcd_set_drawmode(DRMODE_SOLID);
    rb->lcd_set_background(LCD_RGBPACK(251, 233, 102));
    rb->lcd_set_foreground(LCD_BLACK);
    
    kb.selection=0;
    kb.currow=0;
    kb.curcol=0;
    
    rb->lcd_getstringsize("A", &kb.font_width, &kb.font_height);

	inv_keysel(kb,true);

	while (!done)
	{
		button = rb->button_get(true);

		switch(button) 
	        {
	            case UP:
                case UP | BUTTON_REPEAT :
        		    inv_keysel(kb, false);
        	        kb.selection = (kb.selection - 13);
        			if (kb.selection<0) kb.selection+=KEYBOARD_SIZE-1;
        		    inv_keysel(kb, true);
	                break;
	            case DOWN:
                case DOWN | BUTTON_REPEAT :
            		inv_keysel(kb, false);
            	    kb.selection = (kb.selection + 13);
            		if (kb.selection>=KEYBOARD_SIZE) kb.selection-=KEYBOARD_SIZE-1;
            		inv_keysel(kb, true);
	                break; 
		        case LEFT:
                case LEFT | BUTTON_REPEAT :
        			inv_keysel(kb, false);
        			kb.selection = (kb.selection - 1);
        			if (kb.selection<0) kb.selection=KEYBOARD_SIZE-1;
        			inv_keysel(kb, true);
		        	break;
		        case RIGHT:
                case RIGHT | BUTTON_REPEAT :
        			inv_keysel(kb, false);
        			kb.selection = (kb.selection + 1);
        			if (kb.selection>=KEYBOARD_SIZE) kb.selection=0;
        			inv_keysel(kb, true);
        			break;
		        case CANCEL:
                    done=true;
                    break;
               	case SELECT:
		        case SELECT | BUTTON_REPEAT:
        			if (key_chars[kb.selection]<KEYS_ACTIONS) /* then action has been pressed */
        			{
        				switch (key_chars[kb.selection])
        				{
                                        case KEY_BACK :
                                              inv_cursor(kb, false);
                        				      if (kb.currow!=0 || kb.curcol!=0)kb.curcol--;
                        				      if (kb.curcol<0) { 
                                                    kb.curcol=MESSAGE_LENGTH; 
                                                    kb.currow--;
                                              }
                        				      rb->lcd_putsxy(TEXT_XPOS+kb.curcol*kb.font_width, TEXT_YPOS+2+kb.currow*kb.font_height, " ");
                        				      cl.note[note_num].message[kb.currow][kb.curcol]=NULL;
                        				      inv_cursor(kb, true);
                                              break; 
                                        case KEY_HOME :
                                              inv_cursor(kb, false);
                        					  kb.curcol=0;
                        				      inv_cursor(kb, true);
                                              break; 
                                        case KEY_END  :
                                              inv_cursor(kb, false);
                        				      kb.curcol=MESSAGE_LENGTH;
                        				      inv_cursor(kb, true);
                                              break; 
                                        case KEY_DEL  :
                                              inv_cursor(kb, false);
                        				      cl.note[note_num].message[kb.currow][kb.curcol]=NULL;
                        				      rb->lcd_set_background(LCD_WHITE);
                        			          rb->lcd_putsxy(TEXT_XPOS+kb.curcol*kb.font_width, TEXT_YPOS+2+kb.currow*kb.font_height, " ");
                        				      inv_cursor(kb, true);
                                              break; 
                                        case KEY_UP   :
                                              inv_cursor(kb, false);
                                              if (kb.currow!=0) { kb.currow--; }
                                              inv_cursor(kb, true);
                                              break; 
                                        case KEY_LEFT :
                                              inv_cursor(kb, false);
                        				      if (kb.currow!=0 || kb.curcol!=0)kb.curcol--;
                        				      if (kb.curcol<0) { 
                                                    kb.curcol=MESSAGE_LENGTH; 
                                                    kb.currow--;
                                              }
                                              inv_cursor(kb, true);
                                              break; 
                                        case KEY_DOWN :
                                              inv_cursor(kb, false);
                                              if (kb.currow!=MESSAGE_LINES-1) 
                                                  kb.currow++;
                                              inv_cursor(kb, true);
                                              break; 
                                        case KEY_RIGHT:
                                              inv_cursor(kb, false);
                                			  if (kb.curcol==MESSAGE_LENGTH && kb.currow!=MESSAGE_LINES-1) { 
                                                      kb.curcol=0; 
                                                      kb.currow++; 
                                              } else if (kb.currow!=MESSAGE_LINES-1)
                                                      kb.curcol++;
                                              inv_cursor(kb, true);
                                              break; 
                                        }
        			}
        			else
        			{	inv_cursor(kb, false);
        				cl.note[note_num].message[kb.currow][kb.curcol]=key_chars[kb.selection];
        				rb->snprintf(temp,2,"%c",key_chars[kb.selection]);
        				rb->lcd_putsxy(TEXT_XPOS+kb.curcol*kb.font_width, TEXT_YPOS+2+kb.currow*kb.font_height, temp);
        				if (kb.curcol==MESSAGE_LENGTH && kb.currow!=MESSAGE_LINES-1) { 
                              kb.curcol=0; 
                              kb.currow++; 
                        } else if (kb.currow!=MESSAGE_LINES-1)
                              kb.curcol++;
        				inv_cursor(kb, true);
        			}
                    break; 
		}/* end switch */
	}/* end while */
}


/* ################################################################ 
   ##############        Delete specific note        ##############
   ################################################################ */
void delete_note(int y) {
       cl.notes_count--;
       cl.note[y].year=cl.note[cl.notes_count].year;
       cl.note[y].day=cl.note[cl.notes_count].day;
       cl.note[y].month=cl.note[cl.notes_count].month;
       cl.note[y].type=cl.note[cl.notes_count].type;
       cl.note[y].year=cl.note[cl.notes_count].year;
       rb->snprintf(cl.note[y].message[0], MESSAGE_LENGTH, "%s", cl.note[cl.notes_count].message[0]);

       cl.note[cl.notes_count].year=-1;
       cl.note[cl.notes_count].day=-1;
       cl.note[cl.notes_count].month=-1;
       cl.note[cl.notes_count].type=-1;
       cl.note[cl.notes_count].year=-1;
       rb->strcpy(cl.note[cl.notes_count].message[0],""); 
}

/* ################################################################ 
   ##############      View specific note message    ##############
   ################################################################ */
void view_message (int y){
     int i,h;
     char str[MESSAGE_LENGTH];
     
     rb->lcd_set_drawmode(DRMODE_SOLID);
     rb->lcd_set_background(LCD_RGBPACK(251, 233, 102));
     
     rb->lcd_getstringsize("A", NULL, &h);
     
     for (i=0; i<MESSAGE_LINES; i++) {
         rb->snprintf(str, MESSAGE_LENGTH, "%s", cl.note[y].message[i]);
         rb->lcd_putsxy(TEXT_XPOS, TEXT_YPOS+2+i*h, str);
     }
}

/* ################################################################ 
   ########## Draw the frame on the view/add note screen ##########
   ################################################################ */
void draw_frame (int y) 
{
     int h,w;
     char str[15];
     rb->lcd_set_foreground(LCD_BLACK);            
     rb->lcd_getstringsize("Note", &w, &h);
     rb->lcd_putsxy(LCD_WIDTH/2-w/2, 4, "Note");
     
     rb->lcd_set_foreground(LCD_RGBPACK(251, 233, 102));
     rb->lcd_fillrect(TEXT_FRAME_XPOS, TEXT_FRAME_YPOS, TEXT_FRAME_WIDTH, TEXT_FRAME_HEIGHT);
             
     rb->lcd_set_foreground(LCD_BLACK);
     rb->lcd_drawrect(TEXT_FRAME_XPOS, TEXT_FRAME_YPOS, TEXT_FRAME_WIDTH, TEXT_FRAME_HEIGHT);  
     
     if (cl.note[y].year==555) 
          rb->snprintf(str, 11, "%02d/%02d/****", cl.calen[cl.col][cl.row], cl.month+1);
     else 
          rb->snprintf(str, 11, "%02d/%02d/%04d", cl.calen[cl.col][cl.row], cl.month+1, cl.year+1900);

     rb->lcd_set_drawmode(DRMODE_FG);
     rb->lcd_putsxy(TEXT_XPOS, TEXT_FRAME_YPOS+3, str);
     rb->lcd_set_drawmode(DRMODE_SOLID);
}

/* ################################################################ 
   ##############           Draw the menus           ##############
   ################################################################ */
void draw_menu (int menu) 
{
     int i, h, w;
     char str[15];
     
     rb->lcd_getstringsize("A", NULL, &h);
     
     rb->lcd_set_foreground(MENU_1F_COLOR);
     rb->lcd_fillrect(menus[menu][MENU_1F_XPOS], menus[menu][MENU_1F_YPOS], menus[menu][MENU_1F_WIDTH], menus[menu][MENU_1F_HEIGHT]);
     rb->lcd_set_foreground(MENU_2F_COLOR);
     rb->lcd_fillrect(menus[menu][MENU_2F_XPOS], menus[menu][MENU_2F_YPOS], menus[menu][MENU_2F_WIDTH], h*ADD_MENU_ITEMS+2*ADD_MENU_ITEMS+4);
     
     rb->lcd_set_foreground(LCD_BLACK);
     rb->lcd_drawrect(menus[menu][MENU_1F_XPOS], menus[menu][MENU_1F_YPOS], menus[menu][MENU_1F_WIDTH], menus[menu][MENU_1F_HEIGHT]);
     rb->lcd_drawrect(menus[menu][MENU_2F_XPOS], menus[menu][MENU_2F_YPOS], menus[menu][MENU_2F_WIDTH], h*ADD_MENU_ITEMS+2*ADD_MENU_ITEMS+4);
    
     rb->lcd_set_drawmode(DRMODE_FG);
     rb->lcd_set_foreground(LCD_WHITE);
     
     if (menu==DAY_MENU_ADD || menu==DAY_MENU_VIEW){
           rb->snprintf(str, 11, "%02d/%02d/%04d", cl.calen[cl.col][cl.row], cl.month+1,cl.year+1900);
           rb->lcd_getstringsize(str, &w, NULL);
     } else if (menu==MAIN_MENU) {
           rb->snprintf(str, 11, "Main Menu");
           rb->lcd_getstringsize(str, &w, NULL);
     } else {
           rb->snprintf(str, 11, "Menu");
           rb->lcd_getstringsize(str, &w, NULL);
     }
         
     rb->lcd_putsxy(menus[menu][MENU_1F_XPOS]+(menus[menu][MENU_1F_WIDTH]/2-w/2), menus[menu][MENU_1F_YPOS]+3, str);
     
     rb->lcd_set_foreground(LCD_BLACK);
     for (i=0; i<ADD_MENU_ITEMS; i++){
         if (menu_items[menu][i]) {
             if(menu==DAY_MENU_VIEW) {
                      if (i==DM_ADD) {
                         rb->lcd_set_foreground(UNUSED_TEXT_COLOR);
                         rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+i*h+i*2+2, menu_items[menu][i]);
                         rb->lcd_set_foreground(LCD_BLACK);
                      } else {
                         rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+i*h+i*2+2, menu_items[menu][i]);
                      }
             } else if (menu==DAY_MENU_ADD) { 
                      if (i==DM_VIEW || i==DM_DELETE) {
                         rb->lcd_set_foreground(UNUSED_TEXT_COLOR);
                         rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+i*h+i*2+2, menu_items[menu][i]);     
                         rb->lcd_set_foreground(LCD_BLACK);
                      } else {
                         rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+i*h+i*2+2, menu_items[menu][i]);
                      }  
             } else
                 rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+i*h+i*2+2, menu_items[menu][i]);     
         }
     }
     rb->lcd_set_drawmode(DRMODE_SOLID);
     
     rb->lcd_update_rect(menus[menu][MENU_1F_XPOS], menus[menu][MENU_1F_YPOS], menus[menu][MENU_1F_WIDTH], menus[menu][MENU_1F_HEIGHT] + menus[menu][MENU_2F_HEIGHT]);
     
}

/* ################################################################ 
   ##############      Menu navigation function      ##############
   ################################################################ */
bool menu_navigate(int menu, int note_num)
{
     int h, cur, button;
     bool exit=false;
     char str[20];
     
     
     rb->lcd_getstringsize("A", NULL, &h);
     
     if(menu == DAY_MENU_VIEW) cur=1;
     else cur=0;

     while (!exit) {
           
        if (menu==ADD_MENU || menu==VIEW_MENU) {
            rb->lcd_set_foreground(MENU_2F_COLOR);
            rb->lcd_fillrect(menus[menu][MENU_2F_XPOS]+1, menus[menu][MENU_2F_YPOS]+1, 10, h*ADD_MENU_ITEMS+2*ADD_MENU_ITEMS+4-2);
            rb->lcd_fillrect(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+22, 106, 19);
           
            rb->lcd_set_foreground(LCD_BLACK);
            rb->lcd_set_drawmode(DRMODE_FG);
            rb->snprintf(str, sizeof(str), "%s %s", menu_items[menu][ADD_MENU_YEAR], cl.note[note_num].year==555?"All Year":"This Year");
            rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+ADD_MENU_YEAR*h+ADD_MENU_YEAR*2+2, str);
            rb->snprintf(str, sizeof(str), "%s %s", menu_items[menu][ADD_MENU_TYPE], type_name[cl.note[note_num].type]);
            rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+ADD_MENU_TYPE*h+ADD_MENU_TYPE*2+2, str);
            rb->lcd_set_drawmode(DRMODE_SOLID);
            
        } else if (menu==MAIN_MENU) {
               
            rb->lcd_set_foreground(MENU_2F_COLOR);
            rb->lcd_fillrect(menus[menu][MENU_2F_XPOS]+1, menus[menu][MENU_2F_YPOS]+1, 10, h*DM_ITEMS+2*DM_ITEMS+4-2);
            rb->lcd_fillrect(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+1, 131, 19);

            rb->lcd_set_foreground(LCD_BLACK);
            rb->lcd_set_drawmode(DRMODE_FG);
            rb->snprintf(str, sizeof(str), "%s %s", menu_items[menu][MM_FIRST], calen_days[first_week_day]);
            rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+MM_FIRST*h+MM_FIRST*2+2, str);
            rb->snprintf(str, sizeof(str), "%s %s", menu_items[menu][MM_IRIVER], iriver_fw==1?"Yes":"No");
            rb->lcd_putsxy(menus[menu][MENU_2F_XPOS]+11, menus[menu][MENU_2F_YPOS]+MM_IRIVER*h+MM_IRIVER*2+2, str);
            rb->lcd_set_drawmode(DRMODE_SOLID);            
        } else {
               
            rb->lcd_set_foreground(MENU_2F_COLOR);
            rb->lcd_fillrect(menus[menu][MENU_2F_XPOS]+1, menus[menu][MENU_2F_YPOS]+1, 10, h*DM_ITEMS+2*DM_ITEMS+4-2);
        }
        
        rb->lcd_set_foreground(LCD_BLACK);
        xlcd_filltriangle(menus[menu][MENU_2F_XPOS]+4,   menus[menu][MENU_2F_YPOS]+cur*h+cur*2+2, 
                          menus[menu][MENU_2F_XPOS]+4,   menus[menu][MENU_2F_YPOS]+cur*h+cur*2+2+h, 
                          menus[menu][MENU_2F_XPOS]+4+5, menus[menu][MENU_2F_YPOS]+cur*h+cur*2+2+(h-1)/2+1);

        rb->lcd_update_rect(menus[menu][MENU_1F_XPOS], menus[menu][MENU_1F_YPOS], menus[menu][MENU_1F_WIDTH], menus[menu][MENU_1F_HEIGHT] + menus[menu][MENU_2F_HEIGHT]);
        
        button = rb->button_get(true);  
        switch(button) {
                  case CANCEL:
                       exit=true;
                       break;
                  case DOWN:
                  case DOWN | BUTTON_REPEAT:
                       if(menu == DAY_MENU_VIEW){
                           if (++cur==DM_ITEMS)
                               cur=DM_VIEW;
                       } else if (menu == DAY_MENU_ADD) { 
                           if (++cur==DM_ITEMS)
                               cur=0;
                           else if (cur==DM_VIEW)
                               cur =DM_CANCEL;
                           
                       } else if (menu == MAIN_MENU) { 
                         if (++cur==MM_ITEMS)
                             cur=MM_FIRST;                           
                       } else {
                         if (++cur==ADD_MENU_ITEMS)
                             cur=ADD_MENU_DELETE;
                       }
                       break;
                  case UP:
                  case UP | BUTTON_REPEAT:
                       if(menu == DAY_MENU_VIEW){
                           if (--cur<DM_VIEW)
                               cur=DM_CANCEL;
                       } else if (menu == DAY_MENU_ADD) { 
                           if (--cur<0)
                               cur=DM_CANCEL;
                           else if (cur==DM_DELETE)
                               cur =DM_ADD;
                       } else if (menu == MAIN_MENU) { 
                          if (--cur<MM_FIRST)
                              cur=MM_QUIT;
                       } else {
                          if (--cur<ADD_MENU_DELETE)
                              cur=ADD_MENU_DONE;
                       }
                       break; 
                  case SELECT:
                       if (menu==DAY_MENU_ADD || menu==DAY_MENU_VIEW){
                           switch (cur) {
                              case DM_ADD:
                                  rb->lcd_set_background(LCD_WHITE);
                                  rb->lcd_clear_display();
                                  draw_frame(note_num);
                                  keyboard_bitmap(false);
                                  rb->lcd_update();
                                  cl.note[note_num].year=cl.year;
                                  keyboard_loop(note_num);
                                  draw_menu(ADD_MENU);
                                  menu_navigate(ADD_MENU, note_num);
                                  break;
                               case DM_VIEW:
                                  rb->lcd_set_background(LCD_WHITE);
                                  rb->lcd_clear_display();
                                  draw_frame(note_num);
                                  view_message(note_num);
                                  keyboard_bitmap(true);
                                  draw_menu(VIEW_MENU);
                                  rb->lcd_update();
                                  menu_navigate(VIEW_MENU, note_num);
                                  break;
                               case DM_DELETE:
                                  delete_note(note_num);
                                  rb->splash(HZ,true,"Deleted!");
                                  break;
                           }
                           exit=true;        
                       } else if (menu==MAIN_MENU){
                           switch (cur) {
                              case MM_FIRST:
                                  if (++first_week_day==7)
                                      first_week_day=0;
                                  break;
                               case MM_IRIVER:
                                  iriver_fw = iriver_fw == 0 ? 1 : 0;
                                  break;
                               case MM_QUITM:
                                  exit=true;
                                  
                                  break;
                               case MM_QUIT:
                                  return true;
                                  break;
                           }
                       } else { 
                           switch (cur) { 
                               case ADD_MENU_DELETE:
                                  delete_note(note_num);
                                  rb->splash(HZ,true,"Deleted!");
                                  exit=true;
                                  break;
                               case ADD_MENU_YEAR:
                                  cl.note[note_num].year=cl.note[note_num].year!=cl.year?cl.year:555;     
                                  break;
                               case ADD_MENU_EDIT:
                                  rb->lcd_set_background(LCD_WHITE);
                                  rb->lcd_clear_display();
                                  draw_frame(note_num);
                                  view_message(note_num);
                                  keyboard_bitmap(false);
                                  rb->lcd_update();
                                  keyboard_loop(note_num);
                                  draw_menu(menu);
                                  break;
                               case ADD_MENU_TYPE:
                                  if (++cl.note[note_num].type==MAX_NOTESTYPES)
                                     cl.note[note_num].type=0;
                                  break;
                               case ADD_MENU_DONE:
                                  if (menu==ADD_MENU){
                                      cl.note[cl.notes_count].day=cl.calen[cl.col][cl.row];
                                      cl.note[cl.notes_count].month=cl.month+1;
                                      cl.notes_count++;
                                  }
                                  rb->splash(HZ,true,"Done!");
                                  exit=true;
                                  break;
                           }
                       }                
                       break;
        }
         
     }
     return false;
}


/* ################################################################ 
   ##############  Draw the main RockCalendar Screen ##############
   ################################################################ */
void calen_draw(void)
{  
     
     int i,w,h,x,y=0;
     char str[MESSAGE_LENGTH];
     
     calen_init();
     rb->lcd_set_background(LCD_WHITE);
     rb->lcd_clear_display();
     rb->lcd_set_foreground(LCD_RGBPACK(0, 0, 162));
     rb->snprintf(str, 20, "%s %d", month_name[cl.month],(1900 + cl.year));
     rb->lcd_getstringsize(str, &w, &h);
     rb->lcd_putsxy(LCD_WIDTH/2-w/2, MONTH_NAME_YPOS, str);        
     rb->lcd_set_foreground(LCD_BLACK);
     
      for(i=0;i<6;i++) {
        for(x=0;x<7;x++) {
               rb->snprintf(str, 3, "%d", cl.calen[i][x]);         
               
               if (x==6) {
                       rb->lcd_set_foreground(LCD_RGBPACK(192, 192, 192));
                       rb->lcd_fillrect(LEFTMARGIN+6*SQU_WIDTH+6+1, TOPMARGIN+i*SQU_HEIGHT+i+1, SQU_WIDTH, SQU_HEIGHT);
                       rb->lcd_set_foreground(LCD_BLACK);
                       rb->lcd_set_drawmode(DRMODE_FG);
                       if (cl.calen[i][x]!=0) rb->lcd_putsxy(LEFTMARGIN+x*SQU_WIDTH+x+1, TOPMARGIN+i*SQU_HEIGHT+i+2, str);
                       rb->lcd_set_drawmode(DRMODE_SOLID);
               } else if (cl.calen[i][x]!=0 && x !=6) {
                       rb->lcd_set_drawmode(DRMODE_FG);
                       rb->lcd_putsxy(LEFTMARGIN+x*SQU_WIDTH+x+1, TOPMARGIN+i*SQU_HEIGHT+i+2, str);
                       rb->lcd_set_drawmode(DRMODE_SOLID);
               }  

               
               for(y=0;y<=cl.notes_count;y++) {
                              
                    if (cl.note[y].month==cl.month+1 && (cl.note[y].year==cl.year || cl.note[y].year==555) && cl.note[y].day==cl.calen[i][x]) {
                        if(cl.note[y].type==NOTE){
                            rb->lcd_bitmap_transparent(rockcalendar_note, LEFTMARGIN+x*SQU_WIDTH+x+(SQU_WIDTH-NOTE_WIDTH-1), TOPMARGIN+i*SQU_HEIGHT+i+(SQU_HEIGHT-NOTE_HEIGHT-1), NOTE_WIDTH, NOTE_HEIGHT);
                        } else if(cl.note[y].type==FREE_DAY) {
                            rb->lcd_bitmap_transparent(rockcalendar_house, LEFTMARGIN+x*SQU_WIDTH+x+(SQU_WIDTH-HOUSE_WIDTH-1), TOPMARGIN+i*SQU_HEIGHT+i+(SQU_HEIGHT-HOUSE_HEIGHT-1), HOUSE_WIDTH, HOUSE_HEIGHT);
                        } else if(cl.note[y].type==BIRTHDAY){
                            rb->lcd_bitmap_transparent(rockcalendar_balloons, LEFTMARGIN+x*SQU_WIDTH+x+(SQU_WIDTH-BALLOONS_WIDTH-2), TOPMARGIN+i*SQU_HEIGHT+i+(SQU_HEIGHT-BALLOONS_HEIGHT-2), BALLOONS_WIDTH, BALLOONS_HEIGHT);
                        } else if(cl.note[y].type==HOLIDAY) {
                            rb->lcd_set_foreground(LCD_RGBPACK(255, 128, 0));
                            rb->lcd_fillrect(LEFTMARGIN+x*SQU_WIDTH+x+1, TOPMARGIN+i*SQU_HEIGHT+i+1, SQU_WIDTH, SQU_HEIGHT);
                            rb->lcd_set_foreground(LCD_BLACK);
                            rb->lcd_set_drawmode(DRMODE_FG);
                            rb->lcd_putsxy(LEFTMARGIN+x*SQU_WIDTH+x+1, TOPMARGIN+i*SQU_HEIGHT+i+2, str);
                            rb->lcd_set_drawmode(DRMODE_SOLID);
                        }
                    }
                                 
               }

        }
     }

     i = first_week_day;
     for(x=0;x<7;x++) {
          rb->snprintf(str, 4, "%s", calen_days[i]);
          rb->lcd_getstringsize(str, &w, &h);
          rb->lcd_putsxy(LEFTMARGIN+x*SQU_WIDTH+x+(SQU_WIDTH/2-w/2), TOPMARGIN-h, str);                
          rb->lcd_vline(LEFTMARGIN+x*SQU_WIDTH+x, TOPMARGIN, LCD_HEIGHT-BOTTOMMARGIN-1);
          if (i==6) i=0;
          else i++;
     }
     
     rb->lcd_drawrect(LEFTMARGIN, TOPMARGIN, LCD_WIDTH-LEFTMARGIN-RIGHTMARGIN, LCD_HEIGHT-TOPMARGIN-BOTTOMMARGIN); 
         
     for(i=1;i<6;i++) {
          rb->lcd_hline(LEFTMARGIN, LCD_WIDTH-RIGHTMARGIN-1, TOPMARGIN+i*SQU_HEIGHT+i);

     }


     rb->lcd_update();
}

/* ################################################################ 
   ##############     mark day from the calendar     ##############
   ################################################################ */
void calen_cur (bool update) {
       rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
       rb->lcd_fillrect(LEFTMARGIN+cl.row*SQU_WIDTH+cl.row+1, TOPMARGIN+cl.col*SQU_HEIGHT+cl.col+1, SQU_WIDTH, SQU_HEIGHT);
       rb->lcd_set_drawmode(DRMODE_SOLID);
       
       if (update) rb->lcd_update();
}

/* ################################################################ 
   ##############       Main RockCalendar loop       ##############
   ################################################################ */
bool calen_start(void)
{
     int button;
     int y,i;
     struct tm* tm = rb->get_time();
     int tweek_day,tmonth_day;
     bool edit_note=false;
     
     rb->lcd_set_drawmode(DRMODE_SOLID); 

     cl.first_day=(tm->tm_wday+36-tm->tm_mday)%7 - first_week_day;  //takes from calendar.c, thank u ;]
     if (cl.first_day<0) 
          cl.first_day+=7;
                     
     cl.year=iriver_fw==0?tm->tm_year:tm->tm_year-29;
     cl.month=tm->tm_mon;
     
     calen_draw(); 
     
     for(i=0;i<=5;i++){            
         for(y=0;y<7;y++){
             if(cl.calen[i][y]==tm->tm_mday) {                     
                 cl.col=i;
                 cl.row=y;
                 break; break;
             }
         }
     }

     calen_cur(true);

     while (true) {             

              button = rb->button_get(true);  
              switch(button) {
                   case SELECT:
                            edit_note=false;
                            for(y=0;y<cl.notes_count;y++) {
                                if (cl.note[y].month==cl.month+1 && (cl.note[y].year==cl.year || cl.note[y].year==555) && cl.note[y].day==cl.calen[cl.col][cl.row]){ 
                                      draw_menu(DAY_MENU_VIEW);
                                      menu_navigate(DAY_MENU_VIEW, y);
                                      edit_note=true;        
                                      break;
                                }            
                                      
                            }
                            if (!edit_note) {
                               draw_menu(DAY_MENU_ADD);
                               menu_navigate(DAY_MENU_ADD, cl.notes_count);
                            }
                            calen_draw();
                            calen_cur(true);
                            break;
                    case RIGHT:
                    case RIGHT | BUTTON_REPEAT:
                        calen_cur(false);
                        if(cl.row==6 && cl.calen[cl.col+1][0]!=0){ 
                              cl.col++;              
                              cl.row=0;
                        }else if (cl.calen[cl.col][cl.row+1]==0){ 
                             if (cl.month==11){ 
                                 cl.month=0;
                                 cl.year++;
                             }
                             else
                                 cl.month++;    
                             
                             if(cl.last_day==6)
                               cl.first_day=0;
                             else   
                               cl.first_day=cl.last_day+1; 
                                 
                             cl.row=cl.first_day;
                             cl.col=0;
                               
                             calen_draw();
                        } else 
                              cl.row++;
                        
                        calen_cur(true);
                        break;
                    case LEFT:
                    case LEFT | BUTTON_REPEAT:
                        calen_cur(false);
                        if(cl.row==0 && cl.col!=0){ 
                              cl.col--;
                              cl.row=6;
                        }else if (cl.col==0 && cl.row==cl.first_day){ 
                             if (cl.month==0){ 
                                 cl.month=11;
                                 cl.year--;
                             } else
                                 cl.month--; 
                                 
                                    
                             tmonth_day=days_in_month[cl.year%4==0?1:0][cl.month]; 
                             tweek_day=cl.first_day;
                             
                             
                             while(tmonth_day>0){
                                    tweek_day--;                               
                                    if (tweek_day<0) tweek_day=6;  
    
                                    tmonth_day--;
    
                             }            
                             cl.row=cl.first_day==0?6:cl.first_day-1;
                             cl.first_day=tweek_day; 
                             
                             calen_draw(); 
                             if(cl.calen[5][0]==0)
                                  cl.col=4; 
                             else
                                  cl.col=5; 
                           
                        }else 
                              cl.row--;
                              
                        calen_cur(true);
                        break; 
                    case UP:
                    case UP | BUTTON_REPEAT:
                        calen_cur(false);
                        if(cl.col==0 || cl.calen[cl.col-1][cl.row]==0){ 
                              cl.col=5;
                              while (cl.calen[cl.col][cl.row]==0)        
                                 cl.col--;
                         }        
                        else 
                              cl.col--; 
                        
                        calen_cur(true);
                        break;                                    
                    case DOWN:
                    case DOWN | BUTTON_REPEAT:
                        calen_cur(false);    
                        if(cl.col==5 || cl.calen[cl.col+1][cl.row]==0){ 
                              cl.col=0;
                              while (cl.calen[cl.col][cl.row]==0)        
                                 cl.col++;
                         }        
                        else 
                              cl.col++;
                        
                        calen_cur(true); 
                        break;   
                    case NEXT_MONTH:
                    case NEXT_MONTH | BUTTON_REPEAT:
                        calen_cur(false);    
                            
                         if (cl.month==11){ 
                             cl.month=0;
                             cl.year++;
                         }
                         else
                             cl.month++;    
                         
                         if(cl.last_day==6)
                           cl.first_day=0;
                         else   
                           cl.first_day=cl.last_day+1;  
                            
                         cl.row=cl.first_day;
                         cl.col=0;
                         
                         calen_draw();
                         calen_cur(true); 
                         break;                               
                    case PREV_MONTH:
                    case PREV_MONTH | BUTTON_REPEAT:
                         calen_cur(false);      
                         
                         if (cl.month==0){ 
                             cl.month=11;
                             cl.year--;
                         }
                         else
                             cl.month--; 
                             
                         tmonth_day=days_in_month[cl.year%4==0?1:0][cl.month]; 
                         tweek_day=cl.first_day;
                         
                         
                         while(tmonth_day>0){
                                tweek_day--;                               
                                if (tweek_day<0) tweek_day=6;  

                                tmonth_day--;

                         }        
                             
                         cl.first_day=tweek_day; 
                         cl.row=cl.first_day;
                         cl.col=0;
                         
                         calen_draw();
                         calen_cur(true); 
                         break;      
                    case MENU:
                         draw_menu(MAIN_MENU);
                         if (menu_navigate(MAIN_MENU,-1))
                              return true;
                              
                         cl.first_day=(tm->tm_wday+36-tm->tm_mday)%7 - first_week_day;  //takes from calendar.c, thank u ;]
                         if (cl.first_day<0) 
                              cl.first_day+=7;
                                         
                         cl.year=iriver_fw==0?tm->tm_year:tm->tm_year-29;
                    
                         
                         calen_draw(); 
                         
                         for(i=0;i<=5;i++){            
                             for(y=0;y<7;y++){
                                 if(cl.calen[i][y]==tm->tm_mday) {                     
                                     cl.col=i;
                                     cl.row=y;
                                     break; break;
                                 }
                             }
                         }

                         calen_cur(true);
                         break;              
                    case CANCEL:
                            return true;
                            break;    
              }
              
              
              
              

          }    
}     
      
         
         
         
         
         
         
/* this is the plugin entry point */
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{
    (void)parameter;
    rb = api;
 
    /* now go ahead and have fun! */
    rb->lcd_setfont(FONT_SYSFIXED);
    
    xlcd_init(rb);
    configfile_init(rb);

    read_notes();
      
    if (calen_start()) 
         save_notes();
    
    rb->lcd_setfont(FONT_UI);
    return PLUGIN_OK;
}

#endif /* HAVE_LCD_COLOR */



