/*
class  WeatherData
  {
  public:
    int     high;
    int     low;
    int     percip[4];
    string  message[2];


    // Constructor
    WeatherData();

    // Methods
    bool  tick(); // Call this often to keep data up to date.
  }
  */

#include "WeatherData.h"
#include <string>
//#include <cstdio>
#include "curlfuncs.h"

using namespace std;

/**
 * Constructor
 */
WeatherData::WeatherData()
  {
  high = 0;
  low  = 0;
  for( int i=0; i<4; i++ )
    percip[i] = 0;
  message[0] = "NO DATA";
  message[1] = "NO DATA";
  }



/**
 * Move xmlOffset to the character just past "token" in the xmlPage.
 */
void  WeatherData::skipTo( string  token )
  {
  if( !dataOK )
    return;

  xmlOffset = xmlPage.find( token, xmlOffset );
  if( xmlOffset == string::npos )
    {
    dataOK = false;
    xmlOffset = 0;
    }
  else
    xmlOffset += token.size();
  }



/**
 * Return the characters from the current possition up, but not including "token".
 * Leave xmlOffset one past the token.
 */
string  WeatherData::getUpTo( string  token )
  {
  size_t  start = xmlOffset;

  if( !dataOK )
    return;

  skipTo( token );

  if( !dataOK )
    return token; // Return anything
  
  // Return characters we skipped over (not including the token).
  return xmlPage.substr( startOffset, xmlOffset - start - token.size() );
  }


/**
 * Parse the XML looking for interesting data.
 * We really should use an XML parser here, but for now, just search for interesting tags.
 * Sets "dataOK" to false if something should go wrong.
 */
void  WeatherData::parsePage()
  {
  string  strData;
  int     percent;
  xmlOffset = 0;

  // Get the "Low".
  skipTo( "<data" );
  skipTo( "<temperature type=\"minimum\" units=\"Fahrenheit\"" );
  skipTo( "<value>" );
  strData = getUpTo( "</value>" );
  low = atoi( strData );

  // Get the "High".
  skipTo( "<temperature type=\"maximum\" units=\"Fahrenheit\"" );
  skipTo( "<value>" );
  strData = getUpTo( "</value>" );
  high = atoi( strData );

  // Get the chance of "Percipitation".
  skipTo( "<probability-of-precipitation" );
  for( int i=0; i<4; i++ )
    {
    skipTo( "<value>" );
    strData = getUpTo( "</value>" );
    percip[i] = atoi( strData );
    }

  // Get the weather "Summary"
  skipTo( "weather-summary=\"" );
  summary = getUpTo( "\"/>" );


  // Get the English "Messages".
  skipTo( "<wordedForecast" );
  for( int i=0; i<2; i++ )
    {
    skipTo( "<text>" );
    message[i] = getUpTo( "</text>" );
    }
  }




/**
 * Keep the memder data up to date.
 * Return "true" public member data is good. Return "fasle" if there was an error.
 */
bool  WeatherData::ensureUpToDate()
  {
  long  now = lastTime + MIN_TIME_BETWEEN; // TEMP TEMP TEMP

  dataOK = true;
  if( now < lastTime + MIN_TIME_BETWEEN )
    return dataOK; // The data is still good.

  try
    {
    // Initially set a cookie jar to store/retrieve cookies
    CurlSetCookieFile("./cookie.jar");

    // Now retrieve a URL using the GET method.
    //
    // Windways: http://forecast.weather.gov/MapClick.php?lat=33.55&lon=-117.8&FcstType=dwml
    //
    string  url = "http://forecast.weather.gov/MapClick.php?lat=";
    url += LATITUDE + "&lon=" + LONGITUDE + "&FcstType=dwml";

  
    //
    //  Go get "url" into sPage.
    //
    string  sPage;
    if( CurlGetUrl(url.c_str(), &sPage) )
      {
      //
      // Page get was successful.
      //
      parsePage(); // Might set dataOK to false.
      }
    else
      dataOK = false;
    }

  catch(...)
    {
    dataOK = false;
    }

  // Always call this function last to free the resources.
  FreeCurlLibrary();

  return dataOK;
  }