/*
 *  E-Weather - Port of Mike Henderson's wmWeather to an enlightenment epplet.
 *  Copyright (C) 1999,2001 Brandon Streiff <brandon_streiff@yahoo.com>
 *
 *  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 2 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*
 * TODO:
 *  o Port the GrabWeather script to C, eliminating the need for
 *    it and perl.
 *  o Clean up code.
 */
#include <epplet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "font.h"

#define EW_VERSION "0.4b"

typedef struct { int c[3]; } triplet;

Epplet_gadget	exitbut, dispbut, confbut, updateb, helpbut;
RGB_buf		canvas;
Epplet_gadget	drawingarea;

Window		configwindow;
Epplet_gadget	config_station, config_time;
char		cfg_station[24], cfg_time[24];
int		cfg_metric;
Epplet_gadget	config_background_color, config_label_color, config_data_color, config_station_color, config_variable_color;
triplet		background_color, label_color, data_color, station_color, variable_color;
char		line_utc[8]="--:--";
char		line_tmp[8]="---    ";
char		line_dew[8]="---    ";
char		line_prs[8]="---    ";
char		line_hum[8]="---    ";
char		line_wnd[8]="---    ";
char		variablewind; /* really should be a boolean */

void		diediedie(void *data);
void		displaymore();
void		config_cancel(void *data);
void		config_okay(void *data);
void		cfgwindow(void *data);
double		ftoc(char *temp);
double		mitokm(char *temp);
double		pconv(char *temp);
void		weatherupdate();
void		getnewcopy();
void		draw_char(int x, int y, char letter, int r, int g, int b);
void		draw_char_to_buffer(int x, int y, char letter, int r, int g, int b);
void		draw_string(int x, int y, char *string, int r, int g, int b);
void		blankscreen();
void		redrawhandler(void *data, Window win, int x, int y, int w, int h);
void		showbuttons(void *data, Window win);
void		hidebuttons(void *data, Window win);
void		showhelp(void *data);
// to save time typing. . .
#define	redrawscreen() redrawhandler(NULL,Epplet_get_main_window(),0,0,48,48)

triplet parse_hex_triplet(char *string) {
  triplet color;
  int numerical[6];
  int i;
  for (i=0;i<6;i++) {
    if ((string[i] >= '0')&&(string[i] <= '9'))
      numerical[i] = string[i]-'0';
    else if ((string[i] >= 'A')&&(string[i] <= 'F'))
      numerical[i] = 10+string[i]-'A';
    else if ((string[i] >= 'a')&&(string[i] <= 'f'))
      numerical[i] = 10+string[i]-'a';
    else
      numerical[i] = 0;
  }
  color.c[0] = (numerical[0]*16)+numerical[1];
  color.c[1] = (numerical[2]*16)+numerical[3];
  color.c[2] = (numerical[4]*16)+numerical[5];

  return color;
}

void diediedie (void *data) {         /* Kill the epplet */
  Esync();
  Epplet_free_rgb_buf(canvas);
  Epplet_cleanup();
//  Epplet_unremember();
  data = NULL;
  exit(0);
}

void displaymore() {       /* display more ifno. */
  FILE *filetoread;
  char *home=getenv("HOME");
  char txtfilename[255];
  char tempspace[255];
  char buffer[768];
  sprintf(txtfilename, "%s/.wmWeatherReports/%s.TXT", home, Epplet_query_config("STATION"));
  if ((filetoread = fopen(txtfilename, "r")) != NULL) {
    fgets(tempspace, 255, filetoread);
    while (!feof(filetoread)) {
      sprintf(buffer, "%s%s", buffer, tempspace);
      fgets(tempspace, 255, filetoread);
    }
    fclose(filetoread);
    Epplet_dialog_ok(buffer);
  }
  return;
}

void config_cancel(void *data) {
  Epplet_window_destroy(configwindow);
  configwindow = None; return;
  return;
  data = NULL;
}
void config_okay(void *data) {
  /* here's where we write in all the zhummy config stuff. */
  char buffer2[24];

  sprintf(buffer2, "%d", cfg_metric); /* turn the metric int to a char */

  Epplet_modify_config("STATION", Epplet_textbox_contents(config_station));
  Epplet_modify_config("METRIC", buffer2);
  Epplet_modify_config("UPDATE", Epplet_textbox_contents(config_time));
  Epplet_modify_config("BCOLOR", Epplet_textbox_contents(config_background_color));
  Epplet_modify_config("LCOLOR", Epplet_textbox_contents(config_label_color));
  Epplet_modify_config("DCOLOR", Epplet_textbox_contents(config_data_color));
  Epplet_modify_config("SCOLOR", Epplet_textbox_contents(config_station_color));
  Epplet_modify_config("VCOLOR", Epplet_textbox_contents(config_variable_color));

  Epplet_save_config();

  /* update colors */
  background_color = parse_hex_triplet(Epplet_textbox_contents(config_background_color));
  label_color = parse_hex_triplet(Epplet_textbox_contents(config_label_color));
  data_color = parse_hex_triplet(Epplet_textbox_contents(config_data_color));
  station_color = parse_hex_triplet(Epplet_textbox_contents(config_station_color));
  variable_color = parse_hex_triplet(Epplet_textbox_contents(config_variable_color));

  Epplet_window_destroy(configwindow);

  redrawscreen(); /* refresh any color changes. */
  configwindow = None;
  return;
  data = NULL;  
}

void cfgwindow(void *data) {
  /* having the window more than once is not a good thing. */
  if (configwindow) { return; }

  cfg_metric = atoi(Epplet_query_config_def("METRIC", "0"));


  configwindow = Epplet_create_window_config(200,200,"E-Weather " EW_VERSION " Config",
                    config_okay, NULL, NULL, NULL, config_cancel, NULL);

  Epplet_gadget_show(Epplet_create_label(4,4,"Station:",2));
  Epplet_gadget_show(config_station = Epplet_create_textbox(NULL, Epplet_query_config_def("STATION", "KNYC"), 4, 18, 75, 20, 2, NULL, NULL));

  Epplet_gadget_show(Epplet_create_label(85,4,"Update time (sec):",2));
  Epplet_gadget_show(config_time = Epplet_create_textbox(NULL, Epplet_query_config_def("UPDATE", "900"), 85, 18, 75, 20, 2, NULL, NULL)); 

  Epplet_gadget_show(Epplet_create_label(20,50,"Use Metric",2));

  Epplet_gadget_show(Epplet_create_togglebutton(NULL, NULL, 4, 50, 12, 12, &cfg_metric, NULL, NULL));

  Epplet_gadget_show(Epplet_create_label(14,65,"BG Color",2));
  Epplet_gadget_show(Epplet_create_label(95,65,"Label Color",2));
  Epplet_gadget_show(Epplet_create_label(14,155,"Variable Wind Color",2));
  Epplet_gadget_show(Epplet_create_label(14,110,"Data Color",2));
  Epplet_gadget_show(Epplet_create_label(95,110,"Station Color",2));

  config_background_color =	Epplet_create_textbox(NULL, Epplet_query_config_def("BCOLOR", "000000"), 14, 80, 60, 20, 2, NULL, NULL);
  config_label_color =		Epplet_create_textbox(NULL, Epplet_query_config_def("LCOLOR", "7BBEBD"), 95, 80, 60, 20, 2, NULL, NULL);
  config_data_color =		Epplet_create_textbox(NULL, Epplet_query_config_def("DCOLOR", "FFBE52"), 14, 125, 60, 20, 2, NULL, NULL);
  config_station_color =	Epplet_create_textbox(NULL, Epplet_query_config_def("SCOLOR", "C5A5FF"), 95, 125, 60, 20, 2, NULL, NULL);
  config_variable_color =	Epplet_create_textbox(NULL, Epplet_query_config_def("VCOLOR", "FF0000"), 14, 170, 60, 20, 2, NULL, NULL);
  Epplet_gadget_show(config_background_color);
  Epplet_gadget_show(config_label_color);
  Epplet_gadget_show(config_data_color);
  Epplet_gadget_show(config_station_color);
  Epplet_gadget_show(config_variable_color);

  Epplet_window_show(configwindow); /* put the window and gadgets */
  Epplet_window_pop_context();      /* on screen. */

  return;
  data = NULL;
}

double ftoc(char *temp) {		/* Convert Fahrenheit to Celsius */
  double x;
  x = atof(temp);
  x = (x-32)*5/9;
  return x;
}

double mitokm(char *temp) {		/* Convert miles to kilometers */
  double x;
  x = atof(temp);
  x = x / 0.62138;
  return x;
}

double pconv(char *temp) {	/* Convert inHg. to hPa */
  double x;
  x = atof(temp);
  x = x / 0.029529983;
  return x;
}

void weatherupdate() { /* this function *really* needs to be totally rewritten. */
  FILE *datafile;
  char *directions[16] = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
                           "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW" };
  char temp[255];
  char *home=getenv("HOME");
  char tempure[7], dewpnt[7], presre[7], humid[7], wndspd[7], wnddir[7], tempi[7], utctme[7];
  int d;
  char filename[255];
  int i, metric;
  float temp_float;
  metric=atoi(Epplet_query_config("METRIC"));
  sprintf(filename, "%s/.wmWeatherReports/%s.dat", home, Epplet_query_config("STATION"));
  if ((datafile = fopen(filename, "r")) != NULL) {
    fgets(temp, 512, datafile); /* Station location */
    fgets(temp, 512, datafile); /* Date */
    fgets(temp, 512, datafile); /* Cloud cover (i.e., 'overcast') */
    fscanf(datafile, "%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n",
      utctme, tempure, dewpnt, tempi, presre, &d,
      wnddir, wndspd);
    fclose(datafile);

    sprintf(humid,"%d",d);

    temp_float = atof(wndspd);
    /* handle variable wind. this should probably be displayed somewhere. */
    variablewind = 0;
    if (temp_float < 0.0) { temp_float = -temp_float; variablewind = 1; }

    if (temp_float < 10.0) { sprintf(wndspd, "%.2f", temp_float); }
    else if (temp_float < 100.0) { sprintf(wndspd, "%.1f", temp_float); }
    else { sprintf(wndspd, "%.0f", temp_float); }

    if (!metric) {
        sprintf(tempure, "%.1f^F", atof(tempure));
	sprintf(dewpnt, "%.1f^F", atof(dewpnt));
    } else {
	sprintf(tempure, "%.2g^C", ftoc(tempure));
	sprintf(dewpnt, "%.2g^C", ftoc(dewpnt));
	sprintf(presre, "%g", pconv(presre));
    }
    sprintf(humid, "%d%%", d); /* warning: gross ugly hack.
				  for some reason, the humidity string has a bad
				  habit of losing the first character, thus yielding
				  something like '5' for '45', for example.
				  this should be done a lot cleaner. */
/*  sprintf(humid, "%s%%", humid);*/
    i = atoi(wnddir)/22;
    if (i < 0) { variablewind = 1; i = -i; }

    if (!strcmp(wndspd,"0.00")) {
      strcpy(wnddir, "CALM");
    } else if (!strcmp(wnddir,"-9999")) {
      strcpy(wndspd, "-999");
    } else {
      if (!metric)
	sprintf(wnddir, "%s%s", directions[i], wndspd);
      else
	sprintf(wnddir, "%s%.2g", directions[i], mitokm(wndspd));
    }
    if (strstr(utctme, "99:99") != NULL) { strcpy(line_utc,"--:--"); }
    else { strcpy(line_utc,utctme); }
    if (strstr(tempure, "-999") != NULL) { strcpy(line_tmp,"---"); }
    else { strcpy(line_tmp,tempure); }
    if (strstr(dewpnt, "-999") != NULL) { strcpy(line_dew,"---"); }
    else { strcpy(line_dew,dewpnt); }
    if (strstr(presre, "-99") != NULL) { strcpy(line_prs,"---"); }
    else { strcpy(line_prs,presre); }
    if (strstr(humid, "-999%%") != NULL) { strcpy(line_hum,"---"); }
    else { strcpy(line_hum,humid); }
    if (strstr(wndspd, "-999") != NULL) { strcpy(line_wnd,"---"); }
    else { strcpy(line_wnd,wnddir); }
  }
  redrawscreen();
  return;
}
void getnewcopy() {
  char command[17] = "GrabWeather ";
  strcat(command, Epplet_query_config("STATION"));
  Epplet_run_command(command);
  /* Call this again in the number of seconds in the config */
  Epplet_timer(getnewcopy, NULL, atoi(Epplet_query_config("UPDATE")), "download");
  weatherupdate();
  return;
}
void draw_char(int x, int y, char letter, int r, int g, int b) {
  if ((letter>='0')&&(letter<='9')) {
    draw_char_to_buffer(x, y, letter-'0',r,g,b);
  } else if ((letter>='A')&&(letter<='Z')) {
    draw_char_to_buffer(x, y, letter-'A'+14,r,g,b);
  } else if (letter == '.') {
    draw_char_to_buffer(x, y, 11,r,g,b);
  } else if (letter == '^') { /* degree symbol */
    draw_char_to_buffer(x, y, 12,r,g,b);
  } else if (letter == ':') {
    draw_char_to_buffer(x, y, 10,r,g,b);
  } else if (letter == '%') {
    draw_char_to_buffer(x, y, 13,r,g,b);
  } else if (letter == '-') {
    draw_char_to_buffer(x, y, 40,r,g,b);
  }
  return;
}
void draw_char_to_buffer(int x, int y, char letter, int r, int g, int b) {
  int i,j;
  unsigned char *buf = Epplet_get_rgb_pointer(canvas);
  for (i=0;i<3;i++) {
    if ((font_array[(int)letter][i])&1) {
      j = ((y*44)+x)*3;
      buf[j] = r;
      buf[j+1] = g;
      buf[j+2] = b;
    }
    if ((font_array[(int)letter][i])&2) {
      j = (((y+1)*44)+x)*3;
      buf[j] = r;
      buf[j+1] = g;
      buf[j+2] = b;
    }
    if ((font_array[(int)letter][i])&4) {
      j = (((y+2)*44)+x)*3;
      buf[j] = r;
      buf[j+1] = g;
      buf[j+2] = b;
    }
    if ((font_array[(int)letter][i])&8) {
      j = (((y+3)*44)+x)*3;
      buf[j] = r;
      buf[j+1] = g;
      buf[j+2] = b;
    }
    if ((font_array[(int)letter][i])&16) {
      j = (((y+4)*44)+x)*3;
      buf[j] = r;
      buf[j+1] = g;
      buf[j+2] = b;
    }
    x++;
  }
}

void draw_string(int x, int y, char *string, int r, int g, int b) {
  int i;
  for (i=0;i<strlen(string);i++) {
    draw_char(x,y,string[i],r,g,b);
    if ((string[i] == '.')||(string[i] == ':'))
      x+=2;
    else
      x+=4;
  }
}
void blankscreen() {
  int i;
  unsigned char *buf = Epplet_get_rgb_pointer(canvas);
  for (i=0;i<5808;i+=3) {
    buf[i] = background_color.c[0];
    buf[i+1] = background_color.c[1];
    buf[i+2] = background_color.c[2];
  }
}

void redrawhandler(void *data, Window win, int x, int y, int w, int h) {
  if (win==Epplet_get_main_window()) {
    blankscreen();
    draw_string(0,0,  Epplet_query_config("STATION"), station_color.c[0], station_color.c[1], station_color.c[2]);
    draw_string(22,0, line_utc, station_color.c[0], station_color.c[1], station_color.c[2]);
    draw_string(0,6,  "TMP:", label_color.c[0], label_color.c[1], label_color.c[2]);
    draw_string(0,13, "DEW:", label_color.c[0], label_color.c[1], label_color.c[2]);
    draw_string(0,20, "PRS:", label_color.c[0], label_color.c[1], label_color.c[2]);
    draw_string(0,27, "HUM:", label_color.c[0], label_color.c[1], label_color.c[2]);
    draw_string(0,34, "WND:", label_color.c[0], label_color.c[1], label_color.c[2]);

    draw_string(14,6,  line_tmp, data_color.c[0], data_color.c[1], data_color.c[2]);
    draw_string(14,13, line_dew, data_color.c[0], data_color.c[1], data_color.c[2]);
    draw_string(14,20, line_prs, data_color.c[0], data_color.c[1], data_color.c[2]);
    draw_string(14,27, line_hum, data_color.c[0], data_color.c[1], data_color.c[2]);
    if (variablewind)
      draw_string(14,34, line_wnd, variable_color.c[0], variable_color.c[1], variable_color.c[2]);
    else
      draw_string(14,34, line_wnd, data_color.c[0], data_color.c[1], data_color.c[2]);

    Epplet_paste_buf(canvas, Epplet_get_drawingarea_window(drawingarea), 0, 0);
    Esync();
  }
  return;
}
void showbuttons(void *data, Window win) {
  if (win==Epplet_get_main_window()) {
    Epplet_gadget_show(exitbut);
    Epplet_gadget_show(dispbut);
    Epplet_gadget_show(confbut);
    Epplet_gadget_show(updateb);
    Epplet_gadget_show(helpbut);
  }
  return;
  data = NULL;
}
void hidebuttons(void *data, Window win) {
  if (win==Epplet_get_main_window()) {
    Epplet_gadget_hide(exitbut);
    Epplet_gadget_hide(dispbut);
    Epplet_gadget_hide(confbut);
    Epplet_gadget_hide(updateb);
    Epplet_gadget_hide(helpbut);
    Epplet_paste_buf(canvas, Epplet_get_drawingarea_window(drawingarea), 0, 0);
  }
  return;
  data = NULL;
}
void showhelp(void *data) {
  Epplet_show_about("E-Weather");
  return;
  data = NULL;
}

int main(int argc, char **argv) {
  Epplet_Init("E-Weather", EW_VERSION, "A port of wmWeather.", 3, 3, argc, argv, 0);
  Epplet_load_config();
  if (Epplet_query_config("STATION") == NULL)
    Epplet_add_config("STATION", "KNYC");
  if (Epplet_query_config("METRIC") == NULL)
     Epplet_add_config("METRIC", "0");
  if (Epplet_query_config("UPDATE") == NULL)
     Epplet_add_config("UPDATE", "900");
  background_color = parse_hex_triplet(Epplet_query_config_def("BCOLOR", "181818"));
  label_color = parse_hex_triplet(Epplet_query_config_def("LCOLOR", "7BBDBF"));
  data_color = parse_hex_triplet(Epplet_query_config_def("DCOLOR", "FFBF50"));
  station_color = parse_hex_triplet(Epplet_query_config_def("SCOLOR", "C5A6FF"));
  variable_color = parse_hex_triplet(Epplet_query_config_def("VCOLOR", "FF0000"));

  
  canvas = Epplet_make_rgb_buf(44,44);
  drawingarea = Epplet_create_drawingarea(2, 2, 44, 44);

  Epplet_register_focus_in_handler(showbuttons, NULL);
  Epplet_register_focus_out_handler(hidebuttons, NULL);
  Epplet_register_expose_handler(redrawhandler, NULL);

  Esync();
  Epplet_gadget_show(drawingarea);
  exitbut = Epplet_create_button(NULL, NULL, 2, 2, 0, 0, "CLOSE", 0, NULL,  diediedie, NULL);
  dispbut = Epplet_create_button(NULL, NULL, 17, 2, 0, 0, "STOP", 0, NULL, displaymore, NULL);
  confbut = Epplet_create_button(NULL, NULL, 32, 2, 0, 0, "CONFIGURE", 0, NULL, cfgwindow, NULL);
  updateb = Epplet_create_button(NULL, NULL, 32, 32, 0, 0, "REPEAT", 0, NULL, getnewcopy, NULL);
  helpbut = Epplet_create_button(NULL, NULL, 2, 32, 0, 0, "HELP", 0, NULL, showhelp, NULL);


  Epplet_show();
  redrawscreen();

  getnewcopy();
  Esync();
  Epplet_Loop();
  return 0;
}
