import calendar, datetime
import re

def weather_forecast(payload1="",pf1="",payload2="",pf2=""):
    try:
        print payload1
        print pf1
        print payload2
        print pf2
        if payload1=="{1}":
            payload1=""
        if pf1=="{PF.1}":
            pf1=""
        if payload2=="{2}":
            payload2=""
        if pf2=="{PF.2}":
            pf2=""
        global observation_location
        observation_location=""
        global station_id
        station_id=""
        weatherunity="C"
        weatherlang="BR"
        defaultlocation="autoip"
        day=""
        dayf=""
        location=""
        locationf=""
        responsetext=""
        responsespeak=""
        payloadday="payloads\weather_day.xml"
        payloadlocation="payloads\weather_locations.xml"
        responsetext+=">Previsão do tempo{CR}"
        responsetext+="=================={CR}{CR}"
        print responsetext
        if weather_data_available(defaultlocation,weatherlang,weatherunity):
            if payload1!="":
                temp=vc.callAction("PayloadXML.GetValue",payloadday+"&&"+pf1,None)
                if not temp.isError():
                    day=temp.strResult
                    print day
                    day=weather_day(day)
                    dayf=pf1
                else:
                    temp=vc.callAction("PayloadXML.GetValue",payloadlocation+"&&"+pf1,None)
                    if not temp.isError():
                        location=temp.strResult
                        print location
                        locationf=pf1
                    else:
                        #somehow the payload1 is invalid (almost impossible, since VC will not recognize invalid payload)
                        payload1=""

            if payload2!="":
                temp=vc.callAction("PayloadXML.GetValue",payloadday+"&&"+pf2,None)
                if (not temp.isError() and day==""):
                    day=temp.strResult
                    print day
                    day=weather_day(day)
                    dayf=pf2
                else:
                    temp=vc.callAction("PayloadXML.GetValue",payloadlocation+"&&"+pf2,None)
                    if (not temp.isError() and location==""):
                        location=temp.strResult
                        print location
                        locationf=pf2
                    else:
                        #somehow the payload2 is invalid, ie: user has said 2 locations or two days in both payloads
                        payload2=""
            if location=="":
                location="autoip"
            if weather_location_available(location,weatherlang,weatherunity):
                #Here it will show and say the weather
                location==station_id
                if locationf=="":
                    locationf=observation_location
                if day=="":
                    day="D0"
                if dayf=="":
                    dayf='hoje'
                return get_weather(day,dayf,location,locationf,responsetext,responsespeak,weatherlang,weatherunity)
            else:
                #error getting the location information, possibly offline station
                return impossible_get_weather("Não consegui levantar detalhes do local escolhido.","Não consegui levantar detalhes do local escolhido.")
        else:
            return impossible_get_weather("Recebi erros ao tentar consultar o local atual","Recebi erros ao tentar consultar o local atual")
    except:
        pass
    print "Critical error!"+'\n'+traceback.format_exc()
    return False


def weather_data_available(thislocation="autoip",weatherlang="BR",weatherunity="C"):
    temp2=""
    i=0
    while (varHASerror(temp2) and i<=3):
        temp=vc.callAction("WUnder.GetCustom","{D0.weekday}",None)
        temp2=temp.strResult
        #print temp2
        if (varHASerror(temp2) or temp.isError()):
            vc.callAction("WUnder.Change",thislocation+"&&"+weatherlang+"&&"+weatherunity,None)
            time.sleep(0.5)
            i=i+1
        else:
            break
    if i>=4:
        return False
    else:
        return True

def weather_location_available(thislocation="autoip",weatherlang="BR",weatherunity="C"):
    print "checking location availability for "+thislocation
    global observation_location
    observation_location=""
    global station_id
    station_id=""

    temp2=""
    i=0
    temp=vc.callAction("WUnder.GetCustom","{C.station_id}",None)
    temp2=temp.strResult
    while i<=1:
        if thislocation!='autoip':
            if (temp.isError() or varHASerror(temp2) or thislocation.find(temp2,0,len(thislocation))<0):
                vc.callAction("WUnder.Change",thislocation+"&&"+weatherlang+"&&"+weatherunity,None)
                time.sleep(0.5)
                temp=vc.callAction("WUnder.GetCustom","{C.station_id}",None)
                temp2=temp.strResult
            else:
                break
        else:
            if (temp.isError() or varHASerror(temp2)):
                vc.callAction("WUnder.Change",thislocation+"&&"+weatherlang+"&&"+weatherunity,None)
                time.sleep(0.5)
                temp=vc.callAction("WUnder.GetCustom","{C.station_id}",None)
                temp2=temp.strResult
            else:
                break
        i=i+1
    if i>=2:
        return False
    else:
        station_id=temp2
        temp2=""
        i=0
        temp=vc.callAction("WUnder.GetCustom","{C.observation_location}",None)
        temp2=temp.strResult
        while i<=1:
            if (temp.isError() or varHASerror(temp2)):
                vc.callAction("WUnder.Change",thislocation+"&&"+weatherlang+"&&"+weatherunity,None)
                time.sleep(0.5)
                temp=vc.callAction("WUnder.GetCustom","{C.observation_location}",None)
                temp2=temp.strResult
            else:
                break
            i=i+1
        if i>=2:
            return False
        else:
            observation_location=regexlocationf(temp2)
            return True

def regexlocationf(txt):
    print txt
    txt=unicode(txt,'utf-8')
    txt=txt.encode('utf-8')
    print txt
    p = re.compile(r'"full":\s"(.*?)",', re.DOTALL)
    #txt = u" \"full\": \"Santos, Brasil\",\n\n \"city\": \"Santos\",\n\n \"state\": \"\",\n\n \"state_name\": \"Brasil\",\n\n \"country\": \"BZ\",\n\n \"country_iso3166\": \"BR\",\n\n \"zip\": \"00000\",\n\n \"magic\": \"1\",\n\n \"wmo\": \"83782\",\n\n \"latitude\": \"-23.93000031\",\n\n \"longitude\": \"-46.31999969\",\n\n \"elevation\": \"14.00000000\""
    #txt = u" \"full\": \"Santos Aeroporto\, \",\n\n \"city\": \"Santos\",\n\n \"state\": \"\",\n\n \"state_name\": \"Brasil\",\n\n \"country\": \"BZ\",\n\n \"country_iso3166\": \"BR\",\n\n \"zip\": \"00000\",\n\n \"magic\": \"1\",\n\n \"wmo\": \"83782\",\n\n \"latitude\": \"-23.93000031\",\n\n \"longitude\": \"-46.31999969\",\n\n \"elevation\": \"14.00000000\""
    searchObj = re.search(p, txt)
    if searchObj:
        result=unicode(searchObj.group(1),'utf-8')
        print "searchObj.group(1) : ", result
    else:
        result="regex error"
    return result

def varHASerror(txt="",findwhat="rror"):
    if (txt=="" or txt.find(findwhat,0,len(txt))>=0):
        return True
    else:
        return False

def get_weather(thisday="D0",thisdayf="hoje",thislocation="",thislocationf="",responsetext="",responsespeak="",weatherlang="BR",weatherunity="C"):
    global observation_location
    global station_id
    weatherdt='{{var.day}.day}/{{var.day}.month}/{{var.day}.year}'
    CustomWeatherString='Tempo em {Var.friendlyweatherloc}, para {{var.day}.weekday} ('+weatherdt+'): {{var.day}.conditions}, com máxima de {{var.day}.high} graus Célsius e mínima de {{var.day}.low} graus. Há uma chance de {{var.day}.pop}% de chuva, com ventos na média de {{var.day}.avewind} km/h.'
    CustomWeatherString=CustomWeatherString.replace("{var.day}",thisday)
    weatherdt=weatherdt.replace("{var.day}",thisday)
    CustomWeatherString=CustomWeatherString.replace("{Var.friendlyweatherloc}",thislocationf)
    CustomWeatherString=CustomWeatherString.replace(", ,",",")
    CustomWeatherString=CustomWeatherString.replace(",,",",")
    CustomWeatherString=CustomWeatherString.replace("..",".")
    print observation_location
    
    temp2=""
    i=0
    while (varHASerror(temp2) and i<=1):
        temp=vc.callAction("WUnder.GetCustom",CustomWeatherString,None)
        temp2=temp.strResult
        print temp2
        if (varHASerror(temp2) or temp.isError()):
            vc.callAction("WUnder.Change",thislocation+"&&"+weatherlang+"&&"+weatherunity,None)
            time.sleep(0.5)
            i=i+1
    if i>1:
        responsetext+="Não conseguir obter a previsão para "+thisdayf+" em "+thislocationf
        print "strResult=",temp2,"{CR}isError=",temp.isError(),"{CR}thisday=",thisday,"{CR}thislocation=",thislocation
        impossible_get_weather(responsetext,responsespeak)
        return False
    else:
        responsetext+="Estação: "+station_id+"{CR}"
        responsetext+="Local da Estação: "+observation_location+"{CR}"
        #responsetext+=thislocationf+"{CR}"
        responsetext+="Dia: "+thisdayf+"{CR}{CR}"
        responsetext+=temp2
        responsespeak+=temp2
        display_and_say_weather(responsetext,responsespeak)
        return True
    
    
def impossible_get_weather(responsetext="",responsespeak=""):
    responsetext=responsetext
    responsespeak=responsetext
    display_and_say_weather(responsetext,responsespeak)
    return False

def display_and_say_weather(responsetext="",responsespeak=""):
    vc.callAction("OSD.ShowText",responsetext+"&&"+"15000"+"&&"+"-1",None)
    responsespeak=responsespeak.replace("{CR}",". ")
    vc.callAction("TTS.Speak",responsespeak,None)

def weather_day(day=""):
    print day
    thisDay = datetime.datetime.today().weekday()
    if (day=="'hoje'" or day=='hoje' or day=="" or day=="'today'" or day=="today"):
        dVal=0
    elif (day=="'amanhã'" or day=='amanhã' or day=="'tomorrow'" or day=="tomorrow"):
        dVal=1
    else:
        dVal=(int(day)-thisDay+7)%7
    dVal = 'D'+str(dVal)
    return dVal
