{--- 此行必须存在 --------------------------------------------------------------------------
WeatherNetName=中国天气
WeatherMeaning=预报7天天气信息，支持实时温度和湿度的显示
CityFile=tq121.txt
Version=3.0.8.11
----------------------------------------------------------------------------
 Unit Name: tq121.wea
 Author:    8-jie software
 Purpose:   tq121天气插件(仅支持DeskWidget V1.2.8及以上版本)
 History:
  2012-05-05: * 解决温度无法读取的问题
  2009-12-11: * 解决因网页修改导致天气无法读取的问题
  2009-09-11: * 解决了因网页修改导致天气无法读取的问题
  2009-06-24: * 解决了新版网页导致天气无法正常读取的问题
  2009-05-15: * 解决了晚上读取天气预报时没有晚上温度和风力的问题
  2009-02-27: * 解决了读取天气时，第一天有时最低温度高于最高温度
              ! 晚上的天气预报中，最低温度其实是前一天的最低温度
  2009-02-25: * 解决了脚本会出错的问题，并使用阻塞式下载函数以提高脚本效率，降低占用
  2009-02-23: * 解决了晚上刷新天气时，会把明天的天气当作今天的显示，导致所有天气都错一天的问题
              ! 但天气描述仍然显示不正确，会把今天晚上的当明天晚上的显示
  2009-02-03: * 解决了风力描述会显示乱码的问题
  2008-11-23: * 白天网页格式变化了，做了一下更新
  2008-11-11: ! 发现对于亚洲城市,例如“金边”，分析会出错
  2008-11-10: + 更新为新的Weather.com.cn服务器
  2007-02-05: + create this file
----------------------------------------------------------------------------
-----------------------------------------------------------------------------}

const
  DEF_NULLVALUE=-1010;
  DEBUGMODE=false;
  
var
  s,s1,WeatherFileName:string;
  aurl:string;
  lst:TStrings;
  //此天气服务器支持的最大天数
  MaxDays:integer;

  inifn:TIniFile;
  sSec:string;

function StrToWeather(aValue:string; var wDesc:string; isNight:boolean):string;
var
  sMajor,sMinor:string;
  wType:string;
  iType:Integer;
begin
  wType:='NA';
  result:=wType;
  wDesc:='';
  try
  	iType:=StrToInt(aValue);
  except
    iType:=-1;
  end;
  if iType<0 then exit;


  if isNight then
  begin
    case iType of
      0: wType:='Night_Clear';               //无云（晚上）
      1: wType:='Night_CloudyPartly';        //少云（晚上）
      2: wType:='Night_CloudyMostly';        //阴
      3: wType:='Night_Shower';
      7,8,9,10,11,12,21,22,23,24,25: wType:='Night_Rain';//雨（晚上）
      4,5: wType:='Night_Thunderstorms';   //雷雨（晚上）
      6,13,14,15,16,17,19,26,27,28: wType:='Night_Snow';//雪（晚上）
      18,20,29,30,31: wType:='Night_LightPartlyCloudy'; //雾
    end;
  end
  else
  begin
    case iType of
      0: wType:='Sunny';
      1: wType:='CloudyPartly';
      2: wType:='Cloudy';
      3: wType:='LighteningLight';
      4: wType:='Lightening';
      5: wType:='Thunderstorms';
      6: wType:='SnowRainMix';
      7: wType:='RainLight';
      8: wType:='Rain';
      9: wType:='RainHeavy';
      10: wType:='ShowerLight';
      11: wType:='Shower';
      12: wType:='ShowerHeavy';
      13: wType:='SnowWindy';
      14: wType:='SnowLight';
      15: wType:='Snow';
      16: wType:='SnowHeavy';
      17: wType:='Snowflakes';
      18: wType:='Fog';
      19: wType:='Hail';
      20: wType:='Dust';
      21: wType:='RainLight';
      22: wType:='Rain';
      23: wType:='RainHeavy';
      24: wType:='RainIcy';
      25: wType:='RainIcyHeavy';
      26: wType:='SnowLight';
      27: wType:='Snow';
      28: wType:='SnowHeavy';
    end;
  end;
  case iType of
    0: wDesc:='Fair';
    1: wDesc:='Mostly Cloudy';
    2: wDesc:='Cloudy';
    3: wDesc:='Thunder';
    4: wDesc:='Thundershowers';
    5: wDesc:='Thunderstorm';
    6: wDesc:='Sleet';
    7: wDesc:='Light Rain';
    8: wDesc:='Rain';
    9: wDesc:='Heavy Rain';
    10: wDesc:='Showers';
    11: wDesc:='Showers';
    12: wDesc:='Heavy Showers';
    13: wDesc:='Snow Shower';
    14: wDesc:='Light Snow';
    15: wDesc:='Snow';
    16: wDesc:='Heavy Snow';
    17: wDesc:='Heavy Snow';
    18: wDesc:='Fog';
    19: wDesc:='Haze';
    20: wDesc:='Haze';
    21: wDesc:='小雨-中雨';
    22: wDesc:='中雨-大雨';
    23: wDesc:='大雨-暴雨';
    24: wDesc:='RainIcy';
    25: wDesc:='RainIcyHeavy';
    26: wDesc:='Flurries';
    27: wDesc:='Snow';
    28: wDesc:='Heavy Snow';
  end;

  result:=wType;
end;

function Delahref(value:string):string;
var
  s:string;
begin
  result:=value;
  if pos('<a',result)>0 then s:='<a'+StrBetween(result,'<a','>')+'>';
    result:=StrReplace(result,s,'');
end;

function DelHtmlTag(value:string):string;
begin
  result:=value;
  result:=StrReplace(result,'<strong>','');
  result:=StrReplace(result,'<strong >','');
  result:=StrReplace(result,'</strong>','');
  result:=StrReplace(result,'&nbsp;','');
  result:=StrReplace(result,'<em>','');
  result:=StrReplace(result,'</em>','');
  result:=StrReplace(result,'</a>','');
  result:=Delahref(result);  
  result:=Delahref(result);  
end;

procedure ParseDayPart(Row:integer; isNight:boolean);
var
  j:integer;
begin
  //- 温度 -
  s:=StrBetween(lst.strings[Row+9],'<strong>','℃');
  try
    j:=StrToInt(DelHtmlTag(s));
  except
    j:=DEF_NULLVALUE;
  end;
  if (j<>DEF_NULLVALUE) then
  begin
    if isNight then
      inifn.WriteInteger(sSec,'low',j)
    else
      inifn.WriteInteger(sSec,'hi',j);
  end;

  //- 描述和天气图标 -
  if not isNight then
    s:=StrBetween(lst.strings[Row+3],'29x20/d','.gif')
  else
    s:=StrBetween(lst.strings[Row+3],'29x20/n','.gif');
  s:=StrToWeather(s,s1,isNight);
  s1:=StrBetween(lst.strings[Row+6],'target="_blank">','</a>');
  if not isNight then
  begin
    inifn.WriteString(sSec,'am_wType',s);
    inifn.WriteString(sSec,'pm_wType',s);
    inifn.WriteString(sSec,'am_desc',s1);
    inifn.WriteString(sSec,'pm_desc',s1);
  end
  else
  begin
    inifn.WriteString(sSec,'night_wType',s);
    inifn.WriteString(sSec,'night_desc',s1);
  end;
  
  //- Wind -
  s:=trim(lst.strings[Row+14]);
  if s='无持续风向' then s:='';
  s1:=trim(lst.strings[Row+19]);
  if not isNight then
  begin
    inifn.WriteString(sSec,'am_Wind_Direction',s+s1);
    inifn.WriteString(sSec,'pm_Wind_Direction',s+s1);
    inifn.WriteString(sSec,'am_Wind_Level','');
    inifn.WriteString(sSec,'pm_Wind_Level','');
  end
  else
  begin
    inifn.WriteString(sSec,'night_Wind_Direction',s+s1);
    inifn.WriteString(sSec,'night_Wind_Level','');
  end;
end;
  
function ParseString(value: string):boolean;
var
  isNightInfo:boolean; //此值为真时，现在读取的其实是明天的天气信息
  iBase, iIndex,
  i,j,k,ipos:integer;

begin
  result:=false;
  if trim(value)='' then exit;
  iBase:=0;
  iIndex:=0;
  isNightInfo:=false;
  lst:=TStringList.Create;
  inifn:=TIniFile.Create(WeatherFileName);
  try
    if DEBUGMODE then
    begin
      lst.Text:=value;
      lst.SaveToFile('weather.htm');
      //lst.LoadfromFile('weather.htm');
      //lst.Text:=UTF8Decode(lst.Text);
    end;
    lst.Text:=UTF8Decode(value);
    //loginfo('begin parse'+inttostr(lst.count),g_LogFileName);
    //showmessage('begin parse'+inttostr(lst.count));
    if lst.Count<=0 then exit;
    
    MaxDays:=7;
    
    inifn.WriteFloat('system','LastUpdate',now);
    inifn.WriteInteger('system','DayNums',MaxDays);
    inifn.WriteInteger('Today','Flik',DEF_NULLVALUE);

    for i:=0 to lst.Count-1 do
    try
      ipos:=pos('yuBaoTable',lst.strings[i]);
      if ipos<=0 then continue;
      iIndex:=iIndex+1;
      if iBase=0 then
        isNightInfo:=StrBetween(lst.strings[i+3],'">','</td>')='夜间';

      //iBase:=iBase+1;
      sSec:='Day'+IntToStr(iBase);

      if isNightInfo and (iBase=0) then
      begin //如果是夜间，且是第一天
        ParseDayPart(i+3,true);
        //分析当天的一些信息
        
      end
      else
      begin
        ParseDayPart(i+3,false);
        ParseDayPart(i+27,true);
      end;
      
      Inc(iBase);
      result:=true;
      if iBase>MaxDays then exit; //break;
    except
      
    end;
  finally
    lst.Free;
    inifn.free;
  end;
end;

//{"weatherinfo":{"city":"北京","cityid":"101010100","temp":"1","WD":"西南风","WS":"小于3级","SD":"30%","AP":"1029.4hPa","WSE":"<3","time":"17:45","sm":"1.6","isRadar":"1","Radar":"JC_RADAR_AZ9010_JB"}}
//{"weatherinfo":{"city":"北京","cityid":"101010100","temp":"22.2","WD":"西南风","WS":"小于3级","SD":"63%","AP":"1005.3hPa","WSE":"<3","time":"10:10","sm":"2.4","isRadar":"1","Radar":"JC_RADAR_AZ9010_JB"}}
function ParseTmp(value:string):boolean;
var
  s:string;
  j:integer;
  f:Float;
begin
  result:=false;
  inifn:=TIniFile.Create(WeatherFileName);
  try
    //实时温度
    s:=StrBetween(value,'"temp":"','",');
    try
      f:=StrToFloat(s);
      inifn.WriteInteger('Today','Tmp',round(f));
    except
      inifn.WriteInteger('Today','Tmp',DEF_NULLVALUE);
    end;
    //湿度
    s:=StrBetween(value,'SD":"','%"');
    inifn.WriteString('Today','hmid',s);
    //风力
    s:=StrBetween(value,'WD":"','"');
    s:=s+StrBetween(value,'WS":"','"');
    s:=UTF8Decode(s);
    inifn.WriteString('Today','Wind_Direction',s);
    inifn.WriteString('Today','Wind_Level','');
    result:=true;
  finally
    inifn.free;
  end;
end;

procedure RefreshWeatherInfo(aParams:string);
var
  lst:TStrings;
  City,CityCode:string;
  s:string;
begin
  MaxDays:=3;

  //result:=false;
  lst:=TStringList.create;
  try
    //分析参数
    lst.text:=StrToStrings(aParams,';');
    WeatherFileName:=DataPath+'WeatherInfo.ini';//lst.Values['WeatherInfoFile'];
    City:=lst.Values['City'];
    CityCode:=lst.Values['CityCode'];
  finally
    lst.free;
  end;
  
  //读取七天温度
  //aurl:='http://weather.tq121.com.cn/detail.php?city='+City;
  //http://www.weather.com.cn/html/weather/101010100.shtml
  aurl := format('http://www.weather.com.cn/html/weather/%s.shtml',[CityCode]);
  s:='';
  if DownLoadFile(aurl,s,true) then
  begin
	  if ParseString(s) then
	  begin
      //showmessage('TMP');
      //读取实时温度
                  //http://www.weather.com.cn/data/sk/101010100.html
	    aurl:=format('http://www.weather.com.cn/data/sk/%s.html',[CityCode]);
	    if DownLoadFile(aurl,s,true) then
	      ParseTmp(s);
 	    RefreshWidgetWeatherInfo;
	  end
	  else
	  begin
      //showmessage('parse failed');
 	    RefreshWidgetWeatherInfo(false);
 	  end;
  end
  else
 	  RefreshWidgetWeatherInfo(false);
 	ScriptFinished:=true;  
end;
