/*
 * Copyright (c) 2003, Adam Dunkels.
 * All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials provided
 *    with the distribution. 
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.  
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 * This file is part of the Contiki desktop environment
 *
 * $Id: directory.c,v 1.3 2006/05/24 19:34:39 oliverschmidt Exp $
 *
 */

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

#include "ctk.h"
#include "ctk-draw.h"
#include "ek.h"
#include "loader.h"

#include "cfs.h"

#include "program-handler.h"

#define FILENAMELEN 24
#define MAX_NUMFILES 40
#define WIDTH 36
#define HEIGHT 22

static char (filenames[FILENAMELEN + 1])[MAX_NUMFILES];
static struct dsc *dscs[MAX_NUMFILES];
static unsigned char numfiles, morestart, filenameptr;

static struct ctk_window window;

static struct ctk_label description =
  {CTK_LABEL(0, HEIGHT - 1, WIDTH, 1, "")};

static char autoexit = 1;
static struct ctk_button autoexitbutton =
  {CTK_BUTTON(WIDTH/2 - 9, 20, 9, "Auto-exit")};
static char autoexiton[] = "is On ";
static char autoexitoff[] = "is Off";
static struct ctk_label autoexitlabel =
  {CTK_LABEL(WIDTH/2 - 9 + 12, 20, 6, 1, autoexiton)};

static struct ctk_button morebutton =
  {CTK_BUTTON(0, 20, 4, "More")};

static struct ctk_button backbutton =
  {CTK_BUTTON(0, 20, 4, "Back")};

static struct ctk_button reloadbutton =
  {CTK_BUTTON(30, 20, 6, "Reload")};

EK_EVENTHANDLER(directory_eventhandler, ev, data);
EK_PROCESS(p, "Directory browser", EK_PRIO_NORMAL,
	   directory_eventhandler, NULL, NULL);
static ek_id_t id = EK_ID_NONE;

static unsigned char width, height;

#define LOADING_DIR 1
#define LOADING_DSC 2
static char loading = 0;
static struct cfs_dir dir;
/*-----------------------------------------------------------------------------------*/
static void
show_statustext(char *text)
{
  ctk_label_set_text(&description, text);
  CTK_WIDGET_REDRAW(&description);
}
/*-----------------------------------------------------------------------------------*/
static void
startloading(void)
{
  if(cfs_opendir(&dir, "/") != 0) {
    show_statustext("Cannot open directory");
    loading = 0;
  } else {
    loading = LOADING_DIR;
    ek_post(id, EK_EVENT_CONTINUE, NULL);
    numfiles = 0;
  }
}    
/*-----------------------------------------------------------------------------------*/
static void
makewindow(unsigned char i)
{
  unsigned char x, y;

  ctk_window_clear(&window);
  CTK_WIDGET_SET_YPOS(&description, height - 3);
  CTK_WIDGET_SET_WIDTH(&description, width);
  CTK_WIDGET_ADD(&window, &description);

  morestart = i;
  
  x = 0; y = 1;
  for(; dscs[i] != NULL; ++i) {

    if(x + strlen(dscs[i]->icon->title) >= width) {
      y += 5;
      x = 0;
      if(y >= height - 2 - 4) {
	morestart = i;
	break;
      }
    }
    CTK_WIDGET_SET_XPOS(dscs[i]->icon, x);
    CTK_WIDGET_SET_YPOS(dscs[i]->icon, y);
    CTK_WIDGET_ADD(&window, dscs[i]->icon);

    x += strlen(dscs[i]->icon->title) + 2;
  }
  CTK_WIDGET_SET_YPOS(&autoexitbutton, height - 2);
  CTK_WIDGET_ADD(&window, &autoexitbutton);
  CTK_WIDGET_SET_YPOS(&autoexitlabel, height - 2);
  CTK_WIDGET_ADD(&window, &autoexitlabel);
  CTK_WIDGET_FOCUS(&window, &autoexitbutton);

  if(i != morestart) {
    CTK_WIDGET_SET_YPOS(&backbutton, height - 1);
    CTK_WIDGET_ADD(&window, &backbutton);
  } else {
    CTK_WIDGET_SET_YPOS(&morebutton, height - 1);
    CTK_WIDGET_ADD(&window, &morebutton);
  }
  CTK_WIDGET_SET_XPOS(&reloadbutton, width - 8);
  CTK_WIDGET_SET_YPOS(&reloadbutton, height - 1);
  CTK_WIDGET_ADD(&window, &reloadbutton);    
}
/*-----------------------------------------------------------------------------------*/
LOADER_INIT_FUNC(directory_init, arg)
{
  arg_free(arg);
  
  if(id == EK_ID_NONE) {
    id = ek_start(&p);

    width = ctk_draw_width() - 2;
    height = ctk_draw_height() - 3;
  }
}
/*-----------------------------------------------------------------------------------*/
static void
quit(void)
{
  unsigned char i;

  if(loading == LOADING_DIR) {
    cfs_closedir(&dir);
  }
  ctk_window_close(&window);
  for(i = 0; dscs[i] != NULL; ++i) {
    LOADER_UNLOAD_DSC(dscs[i]);
  }
  ek_exit();
  id = EK_ID_NONE;
  LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
static void
read_dirent(void)
{
  static struct cfs_dirent dirent;
  static char message[40];
    
  if(loading == LOADING_DIR) {
    if(cfs_readdir(&dir, &dirent)) {
      cfs_closedir(&dir);
      loading = LOADING_DSC;
      filenameptr = 0;
    } else if(strcasecmp(&dirent.name[strlen(dirent.name) - 4], ".dsc") == 0) {
      strncpy(filenames[numfiles], dirent.name, FILENAMELEN);
      ++numfiles;
      if(numfiles == MAX_NUMFILES) {
	cfs_closedir(&dir);	
	loading = LOADING_DSC;
	filenameptr = 0;
	return;
      }      
      strcpy(message, "Found \"");
      strcpy(message + 7, dirent.name);
      strcpy(message + 7 + strlen(dirent.name), "\"...");
      show_statustext(message);
    }
  }
}
/*-----------------------------------------------------------------------------------*/
static void
load_dirent(void)
{
  static char message[40];
  char *name;
    
  if(loading == LOADING_DSC) {

    name = filenames[filenameptr];
    dscs[filenameptr] = LOADER_LOAD_DSC(name);
    if(dscs[filenameptr] == NULL || filenameptr + 1 >= numfiles) {
      loading = 0;
      makewindow(0);
      show_statustext("Directory loaded");
      ctk_window_redraw(&window);
      return;
    }
    ++filenameptr;
    strcpy(message, "Loading \"");
    strcpy(message + 9, name);
    strcpy(message + 9 + strlen(name), "\"...");
    show_statustext(message);
  }
}
/*-----------------------------------------------------------------------------------*/
EK_EVENTHANDLER(directory_eventhandler, ev, data)
{
  unsigned char i;
  EK_EVENTHANDLER_ARGS(ev, data);

  if(ev == EK_EVENT_INIT) {
    ctk_window_new(&window, width, height, "Directory");

    /*    loaddirectory();*/
    makewindow(0);
    show_statustext("Loading directory...");
    startloading();
    
    ctk_window_open(&window);

  } else if(ev == EK_EVENT_CONTINUE) {
    read_dirent();
    load_dirent();
    if(loading != 0) {
      ek_post(id, EK_EVENT_CONTINUE, NULL);
    }
  } else if(ev == ctk_signal_widget_activate) {
    if(data == (ek_data_t)&reloadbutton) {
      for(i = 0; dscs[i] != NULL; ++i) {
	LOADER_UNLOAD_DSC(dscs[i]);
	dscs[i] = NULL;
      }     
      /*      loaddirectory();*/
      startloading();
      makewindow(0);
      ctk_window_open(&window);
    } else if(data == (ek_data_t)&morebutton) {
      makewindow(morestart);
      ctk_window_open(&window);
    } else if(data == (ek_data_t)&backbutton) {
      makewindow(0);
      ctk_window_open(&window);
    } else if(data == (ek_data_t)&autoexitbutton) {
      autoexit = 1 - autoexit;
      if(autoexit == 1) {
	ctk_label_set_text(&autoexitlabel, autoexiton);
      } else {
	ctk_label_set_text(&autoexitlabel, autoexitoff);
      }
      CTK_WIDGET_REDRAW(&autoexitlabel);
    } else {
      for(i = 0; dscs[i] != NULL; ++i) {
	if(data == (ek_data_t)(dscs[i]->icon)) {
	  program_handler_load(dscs[i]->prgname, NULL);
	  if(autoexit) {
	    ctk_window_close(&window);
	    quit();
	  }
	  break;
	}
      }
    }
  } else if(ev == ctk_signal_widget_select) {
    if(data == (ek_data_t)&reloadbutton) {
      show_statustext("Reload directory");
    } else if(data == (ek_data_t)&morebutton) {
      show_statustext("Show more files");
    } else if(data == (ek_data_t)&backbutton) {
      show_statustext("Show first files");
    } else if(data == (ek_data_t)&autoexitbutton) {
      show_statustext("Exit when loading program");
    } else {
      for(i = 0; dscs[i] != NULL; ++i) {
	if(data == (ek_data_t)(dscs[i]->icon)) {
	  show_statustext(dscs[i]->description);
	  break;
	}
      }
    }
  } else if(ev == ctk_signal_window_close &&
	    data == (ek_data_t)&window) {
    quit();
  } else if(ev == EK_EVENT_REQUEST_EXIT) {
    ctk_window_close(&window);
    quit();
  }
}
/*-----------------------------------------------------------------------------------*/
