/* $Id: cfg.cc,v 1.7 2000/04/18 05:02:20 mac Exp $ */

/*
 * glbiff -- A Mesa/OpenGL-based `xbiff' substitute
 * Copyright (C) 2000  Maciej Kalisiak
 * 
 * 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.
 * 
 */

// This file defines subroutines to handle the
// configuration file

#include <stdio.h>
#include <iostream.h>
#include <ctype.h>

#include "cfg.h"
#include "glbiff.h"

////// constants
const char* const white_space = " \t\n\r";

////// globals
list<mailbox> mboxes;
int check_interval=60;		// in secs
int refresh_period = 0;		// in milisecs
int door_open_frames = 20;	// # of frames for door to open
int cam_swing_frames = 20;	// # of frames for camera swing
int flag_up_frames = 10;	// # of frames for flag up/down

coord my_long_lat(79.5/180*M_PI, 43.75/180*M_PI);	// longitude & latitude

list<Rgb_kf> sky_keyframes;

int* si_var = NULL;

///// prototypes
void handle_mbox_line();
void handle_simple_int_line();
void handle_geo_line();
void handle_skf_line();


//////  possible line types
//
// mailbox <mailbox path> <adds to env count>
// check_interval <check_interval>
// refresh_period <refresh_period>
// door_open_frames <door_open_frames>
// flag_up_frames <flag_up_frames>
// cam_swing_frames <cam_swing_frames>
// geo_coords <lat> <long>
// sky_kf <sky keyframe>

////// code

// I should REALLY be using lex and yacc here; oh well, maybe in future version
// I just didn't have the time

// returns the path to the configuration file to use
char* cfg_file() {
  if(file_config[0] != '~')
    return file_config;
  
  static char buff[1024];
  sprintf(buff, "%s/%s", getenv("HOME"), file_config+1);
  return buff;
}

bool
read_configuration( char* fname ) {
  FILE* fin = fopen( fname, "r" );
  if( !fin ) {
    cerr << "couldn't open config file " << fname << endl;
    return false;
  }

  char buf[1024];
  while (fgets(buf, 1024, fin)) {
    char* line_id = strtok( buf, white_space );	  // UGH! need better method

    // check for a blank line
    if( !line_id )
      continue;
    
    if( !strcmp( line_id, "mailbox" ) )
      handle_mbox_line();
    else if( !strcmp( line_id, "check_interval" ) ) {
      si_var = &check_interval;
      handle_simple_int_line();
    }
    else if( !strcmp( line_id, "refresh_period" ) ) {
      si_var = &refresh_period;
      handle_simple_int_line();
    }
    else if( !strcmp( line_id, "door_open_frames" ) ) {
      si_var = &door_open_frames;
      handle_simple_int_line();
    }
    else if( !strcmp( line_id, "flag_up_frames" ) ) {
      si_var = &flag_up_frames;
      handle_simple_int_line();
    }
    else if( !strcmp( line_id, "cam_swing_frames" ) ) {
      si_var = &cam_swing_frames;
      handle_simple_int_line();
    }
    else if( !strcmp( line_id, "geo_coords" ) )
      handle_geo_line();
    else if( !strcmp( line_id, "sky_kf" ) )
      handle_skf_line();
    else if (!strcmp(line_id, "mailprog")) {
      free(cmd_mail_reader);
      cmd_mail_reader = strdup(line_id + strlen(line_id) + 1);
    } else if (!strcmp(line_id, "newmail")) {
      free(cmd_new_mail);
      cmd_new_mail = strdup(line_id + strlen(line_id) + 1);
    } else {
      cerr << "unkown line in configuration file" << endl;
    }
  }

  fclose( fin );

  sky_keyframes.sort();
  
  // if no sky-keyframes have been provided, put in a standard set
  if(sky_keyframes.size()==0) {
    sky_keyframes.push_back(Rgb_kf(0.0,0.15,0.15,0.15));
    sky_keyframes.push_back(Rgb_kf(0.5,0.5,1.0,1.0));
    sky_keyframes.push_back(Rgb_kf(1.0,0.15,0.15,0.15));    
  } else {
    // make sure the sky-keyframe for sunrise(0.0) and sunset(1.0) are present
    if(sky_keyframes.front().s != 0.0) {
      sky_keyframes.push_front(Rgb_kf(0.0,0.15,0.15,0.15));
    }
    if(sky_keyframes.back().s != 1.0) {
      sky_keyframes.push_back(Rgb_kf(1.0,0.15,0.15,0.15));
    }
  }

  return true;
}


    
void handle_mbox_line() {
  char* str_mb = strtok( NULL, white_space );
  char* str_adds = strtok( NULL, white_space );
  if( !str_mb || !str_adds ) {
    cerr << "syntax:\t mailbox <full_file_name> <adds_to_count>" << endl;
    return;
  }
  mailbox mb( str_mb, (*str_adds=='y'||*str_adds=='Y')?true:false );
  mboxes.push_back( mb );
}

void handle_simple_int_line() {
  char* str = strtok( NULL, white_space );
  if( !str ) {
    cerr << "this command takes a single `int' as an argument" << endl;
    return;
  }
  (*si_var) = atoi( str );

}

// the lattitude is specified as a positive number, followed by 'N' or 'S'
// the longitude is specified as a positive number, followed by 'W' or 'E'
// both are specified in degrees
void handle_geo_line() {
  char* str_lat = strtok( NULL, white_space );
  char* str_long = strtok( NULL, white_space );
  if( !str_lat || !str_long ) {
    cerr << "syntax:\t geo_coords <lat.> <long.>" << endl;
    return;
  }
  char NS = toupper(str_lat[ strlen(str_lat)-1 ]);
  char EW = toupper(str_long[ strlen(str_long)-1 ]);

  if( NS!='N' && NS!='S' ) {
    cerr << "lattitude needs to be followed by an 'N' or an 'S'" << endl;
    return;
  }
  if( EW!='E' && EW!='W' ) {
    cerr << "longitude needs to be followed by an 'E' or a 'W'" << endl;
    return;
  }

  double lat = atof(str_lat)/180.0*M_PI * ((NS=='N')?+1:-1);
  double lng = atof(str_long)/180.0*M_PI * ((EW=='E')?-1:+1);
  my_long_lat = coord( lng, lat );
}

void handle_skf_line() {
  char* str1 = strtok( NULL, white_space );
  char* str2 = strtok( NULL, white_space );
  char* str3 = strtok( NULL, white_space );
  char* str4 = strtok( NULL, white_space );

  if( !str1 || !str2 || !str3 || !str4 ) {
    cerr << "some parameters are missing for the sky keyframe" << endl;
    return;
  }

  Rgb_kf kf( atof(str1), atof(str2)/255.0, atof(str3)/255.0, atof(str4)/255.0 );
  sky_keyframes.push_back( kf );
}


syntax highlighted by Code2HTML, v. 0.9.1