#!/usr/bin/perl
# -*- Perl -*-

#---------------------------------------------------------------------------
#  File:
#      get_weather_sp
#  Description:
#      A perl script that gets the weather forecast for Spain
#  Author:
#      Ricardo Arroyo      ricardo.arroyo@ya.com
#    adapted from get_weather_ca, written by
#      Harald Koch     chk@pobox.com
#    based extensively on get_weather, written by
#      Bruce Winter    bruce@misterhouse.net   http://misterhouse.net
#  Latest version:
#      http://misterhouse.net/mh/bin
#
#  Copyright 2002 Bruce Winter
#
#---------------------------------------------------------------------------
#
# $Id: get_weather_sp 420 2006-04-03 03:12:15Z mattrwilliams $

use strict;

my ($Pgm_Path, $Pgm_Name);
BEGIN {
    ($Pgm_Path, $Pgm_Name) = $0 =~ /(.*)[\\\/](.+)\.?/;
    ($Pgm_Name) = $0 =~ /([^.]+)/, $Pgm_Path = '.' unless $Pgm_Name;
}

my ($Version) = q$Revision: 420 $ =~ /: (\S+)/; # Note: revision number is auto-updated by cvs

#print "Command: $Pgm_Name @ARGV\n";
#print "Version: $Version\n";

use Getopt::Long;
my %parms;
if (!&GetOptions(\%parms, "reget", "h", "help", "v", "debug", "city:s", "zone:s", "state:s", "file=s", "no_log") or
    @ARGV or
    ($parms{h} or $parms{help})) {
    print<<eof;

$Pgm_Name gets weather info

Usage:

  $Pgm_Name [options] 

    -h         => This help text
    -help      => This help text
    -v         => verbose
    -debug     => debug

    -reget     => force HTML fetch

    -city     xxx => xxx is the code for the city you want.
    -zone     xxx => xxx is the zone name. Not used. defined to have compatibility with get_weather (us) version
    -state    xxx => xxx is the state name. not used. defined to have compatibility with get_weather (us) version
    -file     xxx => xxx is the output filename

    -no_log       => Unless this option is used, the results also get filed 
                     into the data_dir/web directory

  Example:
    $Pgm_Name -city YYZ

eof
    exit;
  }

my ($conditions, $forecast, %data);
my %config_parms;


use vars qw(%Weather @Weather_Forecast);

my $caller = caller;
my $return_flag = ($caller and $caller ne 'main') ? 1 : 0;

#use my_lib "$Pgm_Path/../lib/site"; # See note in lib/mh_perl2exe.pl for lib -> my_lib explaination
BEGIN { eval "use lib '$Pgm_Path/../lib', '$Pgm_Path/../lib/site'" } # Use BEGIN eval to keep perl2exe happy

require 'handy_utilities.pl';       # For read_mh_opts funcion
&main::read_mh_opts(\%config_parms, $Pgm_Path);

use HTML::TableExtract;
use Date::Parse;
use Date::Format;

$parms{city}  = $config_parms{weather_city} unless $parms{city};
$parms{city}  = 'SPXX0050'                  unless $parms{city};

my $WeatherURL;
$WeatherURL = sprintf 'http://es.weather.yahoo.com/SPXX/%s/index_c.html', $parms{city};

my $f_weather_html = "$config_parms{data_dir}/../web/ia5/outside/weather_local.html";
my $f_weather_data = "$config_parms{data_dir}/weather_data";

my $debug = 1 if ($parms{debug});

###############
# get weather #
###############

#my $weather_time = (stat($f_weather_html))[9];
#if ($parms{reget} or
#    (-s $f_weather_html < 10) or
#    ((time - $weather_time) > 30*60)
#) {
    get_url_ua($WeatherURL, $f_weather_html);
#}

#################
# parse weather #
#################

print "parsing weather data from $f_weather_html\n" if $parms{v};
&parse_weather_sp($f_weather_html);

################
# save weather #
################

print "saving weather data to $f_weather_data\n" if $parms{v};
&save_weather_sp($f_weather_data);

exit(0);

###############
# subroutines #
###############

# from get_url
sub get_url_ua {
    my $url = shift;
    my $file = shift;

    use LWP::UserAgent;

    my $ua = new LWP::UserAgent;
    $config_parms{proxy} = $ENV{HTTP_PROXY}           unless $config_parms{proxy};
    $ua -> proxy(['http', 'ftp'] => $config_parms{proxy}) if $config_parms{proxy};

    $ua->timeout([120]);         # Time out after 60 seconds 
    $ua->env_proxy(); 

    my $request = new HTTP::Request('GET', $url);
    my $response;

    print "Retrieving (with ua) $url into $file ...\n" unless $config_parms{quiet};
    if ($file eq '/dev/null') {
        $response = $ua->simple_request($request);
    }
    else {
        $response = $ua->simple_request($request, $file);
    }

    if ($response->is_error()) {
        printf "error: %s\n", $response->status_line;
    }
}


# There is an HTML weather page on disk. Parse the weather data out of it and
# save the results in a file so that the parent MH process can read them back
# in.
#
sub parse_weather_sp {
    my $file = shift;
    my $html = &file_read($file);

    %Weather = ();
    @Weather_Forecast = ();

    # remove font modificators
    $html =~ s/<strong>//gs;
    $html =~ s/<\/strong>//gs;
    $html =~ s/<small>//gs;
    $html =~ s/<\/small>//gs;
    $html =~ s/<b>//gs;
    $html =~ s/<\/b>//gs;
    $html =~ s/\&nbsp;/ /gs;
    $html =~ s/<td>//gs;
    $html =~ s/<\/td>//gs;
    $html =~ s/<font size=-1>//gs;
    $html =~ s/<\/font>//gs;

    # find the start of the actual data
    $html =~ s/.*Hoy//s;
    $html =~ s/\&\#176;/\/gs;
    $html =~ s/.*$//m;

print STDERR $html if ($debug);

    ($html =~ m/\<font size=\+2 face=Arial\>(\d*)/i) &&
        ($Weather{TempOutdoor} = $1);
print STDERR "TempOutdoor|$Weather{TempOutdoor}|\n" if ($debug);

    $html =~ m/\<font size=-2 face=Arial\>(.*)\s+CEST/i;
    # convert the strangely formatted UTC timestamp to local time.
    my $tmp = $1;
print STDERR "Time Observed|$tmp|\n" if ($debug);

    $Weather{TimeObserved} = str2time($tmp);

    ($html =~ m/<font size=-2 face="Arial,Helvetica">\s*([^<]+)/i) &&
	($Weather{Conditions} = $1);
print STDERR "Conditions|$Weather{Conditions}|\n" if ($debug);

    ($html =~ m/mx\.\s+(\d*)/i) &&
        ($Weather{TempMaxOutdoor} = $1);
print STDERR "TempMaxOutdoor|$Weather{TempMaxOutdoor}|\n" if ($debug);

    ($html =~ m/mn\.\s+(\d*)/i) &&
        ($Weather{TempMinOutdoor} = $1);
print STDERR "TempMinOutdoor|$Weather{TempMinOutdoor}|\n" if ($debug);

    if ($html =~ m/Presin\s+atmosfrica\s*:\s*([^<]+)/i) {
	$Weather{Barom} = $1;
        $Weather{Barom} =~ s/\D//g;
print STDERR "Barom|$Weather{Barom}|\n" if ($debug);
    }

    ($html =~ m/Visibilidad\s*:\s*([^<]+)/i) &&
	($Weather{Visibility} = $1);
print STDERR "Visibility|$Weather{Visibility}|\n" if ($debug);

    ($html =~ m/Humedad\s*:\s*([^<]+)/i) &&
	($Weather{HumidOutdoor} = $1);
print STDERR "HumidOutdoor|$Weather{HumidOutdoor}|\n" if ($debug);

    ($html =~ m/Punto\s+de\s+condensacin\s*:\s*([^<]+)/i) &&
	($Weather{DewOutdoor} = $1);
print STDERR "DewOutdoor|$Weather{DewOutdoor}|\n" if ($debug);

    if ($html =~ m/Viento\s*:\s*(Direccin)*\s*([^<]+)/i) {
	my $wind = $2;
	$wind =~ s/\s*$//;

	$Weather{Wind} = $wind;
print STDERR "Wind|$Weather{Wind}|, " if ($debug);
	$wind =~ /^\s*([A-Z,a-z]*)\s*\/(\d+)\s*Km\/h/;
	$Weather{WindAvg} = $Weather{WindAvgSpeed} = $2;
	$Weather{WindAvgDir} = convert_to_degrees($1);
print STDERR "WindAvgDir|$Weather{WindAvgDir}|, " if ($debug);
print STDERR "WindAvg|$Weather{WindAvg}|\n" if ($debug);

	if ($wind =~ /gusting to (\d+)/) {
	    $Weather{WindGust} = $Weather{WindGustSpeed} = $1;
	    $Weather{WindGustDir} = $Weather{WindAvgDir};
	}
	else {
	    $Weather{WindGust} = $Weather{WindGustSpeed} = $Weather{WindAvgSpeed};
	    $Weather{WindGustDir} = $Weather{WindAvgDir};
	}
    }

    ($html =~  m/Salida\s*del\s*sol\s*:*\s*([^<]+)/i) &&
	($Weather{Sunrise} = $1);
print STDERR "Sunrise|$Weather{Sunrise}|, " if ($debug);
    ($html =~  m/Puesta\s*del\s*sol\s*:*\s*([^<]+)/i) &&
	($Weather{Sunset} = $1);
print STDERR "Sunset|$Weather{Sunset}|\n" if ($debug);

### GET FORECAST
    
    my $forecast = $html;
    $forecast =~ s/.*<td bgcolor=cc6600><font size=-3>35\+//s;
#print STDERR "Forecast: |$forecast|\n" if ($debug);

    $forecast =~ s/\s*<tr>\s*//gs;
    $forecast =~ s/\s*<\/tr>\s*/\n/gs;
    $forecast =~ s/\s*<\/table>\s*/\n/gs;

    my @forecast = split(/\n/, $forecast);
    my $days = $forecast[2];
    $days =~ s/\<table.*?\>//gs;
    $days =~ s/\<td.*?\>//gs;
    $days =~ s/\<font.*?\>//gs;
    $days =~ s/^\<br\>//s;
print STDERR "\$days: |$days|\n" if ($debug);
    my @days = split(/<br>/, $days);
print STDERR "\@days: |@days|\n" if ($debug);

    my (@conditions, $conditions);
    for (my $i = 0; $i <= $#days; $i++) {
print STDERR "$#days, $i\n" if ($debug);
        $conditions = $forecast[3+$i*2];
        ($conditions =~ m/^.*alt=\"(.*)\".*/i) &&
            push (@conditions, $1);
    }
print STDERR "\@conditions: |@conditions|\n" if ($debug);

    my (@tempmax, @tempmin);
    my $temps = $forecast[3+$#days*2+2];
    $temps =~ s/\<table.*?\>//gs;
    $temps =~ s/\<td.*?\>//gs;
    $temps =~ s/\<font.*?\>//gs;
    $temps =~ s/mx\./\<br\>/gs;
    $temps =~ s/mn\.//gs;
    $temps =~ s/\s+//gs;
    $temps =~ s/^\<br\>//s;
print STDERR "\$temps |$temps|\n" if ($debug);
    my @temps = split(/<br>/, $temps);
print STDERR "\@temps |@temps|\n" if ($debug);
    for ( my $i = 0; $i <= $#temps; $i += 2) {
	    push(@tempmax, $temps[$i]);
	    push(@tempmin, $temps[$i+1]);
    }
print STDERR "\@tempmax |@tempmax|\n" if ($debug);
print STDERR "\@tempmin |@tempmin|\n" if ($debug);

    for (my $i = 0; $i <= $#days; $i++) {
	    push(@Weather_Forecast, $days[$i]);
	    push(@Weather_Forecast, $conditions[$i]);
	    push(@Weather_Forecast, $tempmax[$i]);
	    push(@Weather_Forecast, $tempmin[$i]);
    }
#    @Weather_Forecast = @forecast;
}


sub save_weather_sp {
    my $file = shift;

    # save the data for import by parent
    my ($key, $perl, $line);
    
    $perl = '%Weather=(' . "\n";
    foreach $key (keys(%Weather)) {
	# cleanup the text
	my $data = $Weather{$key};
	$data =~ s/\s*(\xb0|&deg;)\s*[C]*//g;

	$data =~ s/\s*%\s*//g;
#	$data =~ s;\s*km/h\s*;;g;
	$data =~ s/\s*kPa\s*//g;
	$data =~ s/\s*\s*//g;

	$perl .= '    ' . $key . ' => ' . "'" . $data . "',\n";
    }
    $perl .= ');' . "\n";

    $perl .= '@Weather_Forecast=(';
    for (my $i = 0; $i <= $#Weather_Forecast; $i += 4) { 
	$perl .= "\n    '" . $Weather_Forecast[$i] . "',";
	$perl .= "    '" . $Weather_Forecast[$i+1] . "',";
	$perl .= "    '" . $Weather_Forecast[$i+2] . "',";
	$perl .= "    '" . $Weather_Forecast[$i+3] . "',";
    }
    $perl =~ s/,$//; # remove trailing comma
    $perl .= "\n" . ');' . "\n";

    main::file_write($file, $perl);
}

# convert text wind direction to degrees.
sub convert_to_degrees {
    my $text = shift;
    my $dir;

    ($text eq 'N')   && ($dir = 0);
    ($text eq 'n')   && ($dir = 0);
    ($text eq 'NNE') && ($dir = 22);
    ($text eq 'NE')  && ($dir = 45);
    ($text eq 'Noreste')  && ($dir = 45);
    ($text eq 'ENE') && ($dir = 67);

    ($text eq 'E')   && ($dir = 90);
    ($text eq 'e')   && ($dir = 90);
    ($text eq 'ESE') && ($dir = 112);
    ($text eq 'SE')  && ($dir = 135);
    ($text eq 'Sureste')  && ($dir = 135);
    ($text eq 'SSE') && ($dir = 157);

    ($text eq 'S')   && ($dir = 180);
    ($text eq 's')   && ($dir = 180);
    ($text eq 'SSO') && ($dir = 202);
    ($text eq 'SO')  && ($dir = 225);
    ($text eq 'Suroeste')  && ($dir = 225);
    ($text eq 'OSO') && ($dir = 247);

    ($text eq 'O')   && ($dir = 270);
    ($text eq 'o')   && ($dir = 270);
    ($text eq 'Oeste')   && ($dir = 270);
    ($text eq 'ONO') && ($dir = 292);
    ($text eq 'NO')  && ($dir = 315);
    ($text eq 'Noroeste')  && ($dir = 315);
    ($text eq 'NNO') && ($dir = 337);

    return $dir;
}


