#!/usr/bin/perl

#use utf8;
use strict;
use CGI;
use Digest::SHA qw(
    sha1_base64
    sha1_hex
);

use Opals::Context;
use Opals::Template_ajax qw(
    tmpl_read
    tmpl_write
    tmpl_preference
);
use Opals::Locale qw(
    loc_getMsgFile
    loc_write
);
use POSIX qw(
    ceil
    floor
);
use JSON;

use LWP::UserAgent;
use REST::Client;
my $dbh = Opals::Context->dbh();
END { $dbh->disconnect(); }
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
my $cgi      = CGI->new;
my $input    = $cgi->Vars();
my ($permission, $cookie, $template) = tmpl_read(
    {
        dbh             => $dbh,
        cgi             => $cgi,
        tmplFile        => 'ajax/portlet/getWeather.tmpl',
        
    }
);

    my $zipCode = $input->{'zipCode'};
    my $unit    = $input->{'unit'};
    $unit=uc($unit);
    my $rootDir   = Opals::Context->config('rootDir');
    my $yahooWeather="Not available";
    my ($city,$region,$country,$condition,$wind,$humidity,$icon,$temp)=("","","","","","","","");
    my ($windSpeed,$windDirection,$forcast)=("","",[]);
    my $forecast_conditions=[];
 
    my $msgValMap ={};
    my $pageMsgMap           =loc_getMsgFile('/homeTab.msg',{});
    loc_write($template,$pageMsgMap);
    my $unitSys=($unit eq "C")?"metric":"US";
    my $woeid= getWoeid($zipCode);
    my $rs={};
    if(!defined $woeid || $woeid eq ''){
        my $country = Opals::Context->preference('country');
        $woeid= getWoeid("$zipCode $country");
    }
    if($woeid ne ""){
        my $w    = getWeather($woeid,$unitSys);
        if($w){
            $city   = $w->{'location'}->{'city'};
            $region = $w->{'location'}->{'region'};
            $country= $w->{'location'}->{'country'};
            $city  .= ($region ne "")? ", " .$region : '';
            $city  .= ($country ne "")? " " .$country : '';
            $icon       = sprintf("/theme/opals/image/%s.png", $w->{'item'}->{'condition'}->{'code'});
            $rs={zipCode=>$zipCode,
                city=>$city,
                condition=>$w->{'item'}->{'condition'}->{'text'},
                windSpeed=>$w->{'wind'}->{'speed'},
                windDirection=>$w->{'wind'}->{'direction'},
                humidity=>$w->{'atmosphere'}->{'humidity'},
                icon=>$icon,
                temp=>$w->{'item'}->{'condition'}->{'temp'},
                forecast=>$w->{'item'}->{'forecast'}            
                };

           
        }
    }

print "Content-type: text/plain\n\n";

print   to_json({weather=>$rs},{pretty=>1});


=item    
    $template->param(zipCode=>$zipCode,
                    city=>$city,
                    condition=>$condition,
                    windSpeed=>$windSpeed,
                    windDirection=>$windDirection,
                    humidity=>$humidity,
                    icon=>$icon,
                    temp=>"$temp",
                     );
  
    $template->param(forecast_conditions=>$forcast) if(scalar(@$forcast)>0);
    
 
 
tmpl_write($dbh, $cgi, $cookie, $template);
=cut
###############################################################################===============================================================================
sub fahrenheitToCelsius{
    my($f)=@_;
    my $c =(5/9)*($f-32);
    return sprintf("%.0f",$c);
}
#===============================================================================
# Fri, Aug 31, 2012 @ 10:35:03 EDT
#
sub getWoeid{
    my ($location)=@_;
    my $woeid="";
    my $url_woeid="https://query.yahooapis.com/v1/public/yql?q=select woeid from geo.places where text=\"$location\" limit 1&diagnostics=true&format=xml";
    #my $userAgent = LWP::UserAgent->new(agent   => 'OPALS',
    #                                    timeout =>5000);
    #my $request = HTTP::Request->new(GET =>$url_woeid ); 
    #my $response = $userAgent->request($request );
    my $restClient=REST::Client->new({timeout => 60});
    $restClient->GET($url_woeid);
    my $maxForcast=3;
    if($restClient->responseCode =='200' ){
        my $xml=$restClient->responseContent;        
        if($xml =~ m/<results>([\s|\r|\n]*)<place (.*?)>([\s|\r|\n]*)<woeid>(.*)<\/woeid><\/place><\/results>/g){
            $woeid=$4;
        }
    }
    return $woeid;

    
}
##
#===============================================================================
# Fri, Aug 31, 2012 @ 10:35:03 EDT
#
sub getWeather{
    my ($woeid,$unit)=@_;
    my $url_weather="https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid=\"$woeid\"&format=json";
    #my $userAgent = LWP::UserAgent->new(agent   => 'OPALS',
    #                                    timeout =>5000);
    #my $request = HTTP::Request->new(GET =>$url_weather ); 
    #my $response = $userAgent->request($request );
    my $restClient=REST::Client->new({timeout => 60});
    $restClient->GET($url_weather);
    my $response = $restClient->responseContent;
    my $maxForcast=3;
    my $w ={};
    #if($response->is_success){
    if($restClient->responseCode =='200' ){
        #my $jsonStr=$response->content;   
        my $jsonStr=$restClient->responseContent;   
        my $rs=decode_json($jsonStr);
        #open debug, ">/tmp/www";print debug to_json($w,{pretty=>1}); close debug;
        $w =$rs->{"query"}->{"results"}->{"channel"};
         my $dirMap={0=>'N',1=>'NE',2=>'E',3=>'SE',4=>'S',5=>'SW',6=>'W',7=>'NW'};
         my $d =int($w->{"wind"}->{"direction"});
         my $n =floor($d/90);
         my $r =$n+ $d%90>0?1:0;
         my $wd=($n+$r)%8;
         $w->{"wind"}->{"direction"} = $dirMap->{$wd};
         splice @{$w->{"item"}->{"forecast"}},5,5;
         foreach my $fc(@{$w->{"item"}->{"forecast"}}){
            $fc->{"day_of_week"}=$fc->{"day"};
            $fc->{'icon'}=sprintf("/theme/opals/image/%s.png", $fc->{'code'});
        }

        if(defined $unit && $unit eq 'metric'){
             $w->{'wind'}->{'speed'}=int($w->{"wind"}->{"speed"}/0.6214) ." kmph";
            $w->{'item'}->{'condition'}->{'temp'}=fahrenheitToCelsius($w->{'item'}->{'condition'}->{'temp'});
             $w->{'item'}->{'condition'}->{'temp'}=sprintf("%2d &deg; C",$w->{'item'}->{'condition'}->{'temp'});
            foreach my $fc(@{$w->{"item"}->{"forecast"}}){
                $fc->{"high"}=fahrenheitToCelsius($fc->{"high"});
                $fc->{"low"}=fahrenheitToCelsius($fc->{"low"});
            }
        }
        else{
             $w->{'wind'}->{'speed'} .=" mph";
             $w->{'item'}->{'condition'}->{'temp'}=sprintf("%2d &deg; F",$w->{'item'}->{'condition'}->{'temp'});
        }

        
    }
    return $w;

}
#===============================================================================
# Fri, Aug 31, 2012 @ 10:35:03 EDT
#
sub parseYahooWeather{
    my ($xml,$unit)=@_;
    my $weather={};
    $weather->{"forcast"}=[];
    my $itemList=[];
   
    while($xml=~ s/(.*)(<image>(.*?)<\/image>)(.*)/$1$4/s){}
    
    while($xml=~ s/(.*)(<item>(.*?)<\/item>)(.*)/$1$4/s){
        push @$itemList,$2;
    }
    if($xml=~ s/(.*)(<link>(.*?)<\/link>)(.*)/$1$4/s){
        $weather->{'fullForcastLink'}=$3;
    }

    if($xml=~ s/(.*)(<yweather:location (.*?)\/>)(.*)/$1$4/s){
        my $locXml=$3;
        foreach my $f qw(region city  country){
            if($locXml =~ s/$f=\"(.*?)\"//gi){
                $weather->{'location'}->{$f}=$1;
            }
        }
    }
    
    if($xml=~ s/(.*)(<yweather:wind (.*?)\/>)(.*)/$1$4/s){
        my $windXml=$3;
        foreach my $f qw(Direction Speed){
            if($windXml =~ s/$f=\"(.*?)\"//gi){
                $weather->{"currentCond"}->{"wind$f"}=$1;
            }
        } 
        my $dirMap={0=>'N',1=>'NE',2=>'E',3=>'SE',4=>'S',5=>'SW',6=>'W',7=>'NW'};
        my $d =int($weather->{"currentCond"}->{"windDirection"});
        my $n =floor($d/90);
        my $r =$n+ $d%90>0?1:0;
        my $wd=($n+$r)%8;
        $weather->{"currentCond"}->{"windDirection"} = $dirMap->{$wd};

    }
    if($xml=~ s/(.*)(<yweather:atmosphere (.*?)\/>)(.*)/$1$4/s){
        my $aspXml=$3;
        if($aspXml =~ s/humidity=\"(.*?)\"//gi){
            $weather->{"currentCond"}->{'humidity'}=$1;
        }
       
    }
    my $itemXml=@$itemList[0];
    if($itemXml=~ s/(.*)(<yweather:condition (.*?)\/>)(.*)/$1$4/s){
        my $condXml=$3;
        foreach my $f qw(code text temp ){
            if($condXml =~ s/$f=\"(.*?)\"//gi){
                $weather->{"currentCond"}->{"$f"}=$1;
            }
        }
        while($itemXml =~ s/(.*)(<yweather:forecast (.*?)\/>)(.*)//){
            my $condXml=$3;
            my $fc={};
            foreach my $f qw(date day code high low text){
                if($condXml =~ s/$f=\"(.*?)\"//gi){
                    $fc->{$f}=$1;
                }
            }
            $fc->{'day_of_week'}=$fc->{'day'};
            $fc->{'icon'}=sprintf("/theme/opals/image/%s.png", $fc->{'code'});
            push @{$weather->{"forcast"}} ,$fc;
        }
       
    }
    if(defined $unit && $unit eq 'metric'){
        $weather->{"currentCond"}->{"windSpeed"} =int($weather->{"currentCond"}->{"windSpeed"}/0.6214) ." kmph";
        $weather->{"currentCond"}->{"temp"} = fahrenheitToCelsius($weather->{"currentCond"}->{"temp"});
        $weather->{"currentCond"}->{"temp"} = sprintf("%2d &deg; C",$weather->{"currentCond"}->{"temp"});
        foreach my $fc(@{$weather->{"forcast"}}){
            $fc->{"high"}=fahrenheitToCelsius($fc->{"high"});
            $fc->{"high"}=sprintf("%2d ",$fc->{"high"});
            $fc->{"low"}=fahrenheitToCelsius($fc->{"low"});
            $fc->{"low"}=sprintf("%2d ",$fc->{"low"});
        }
    }
    else{
        $weather->{"currentCond"}->{"temp"} .= " &deg; F";
        $weather->{"currentCond"}->{"windSpeed"} .=" mph";
    }
    return $weather;
}



