import obspython as obs
import json
import math
import urllib.request
import urllib.error
from datetime import datetime

appid       = ""
location    = ""
language    = ""
units       = ""
url         = ""
interval    = 30
source_name = ""

# ------------------------------------------------------------

def update_text():
	global appid
	global location
	global language
	global units
	global url
	global interval
	global source_name

	source = obs.obs_get_source_by_name(source_name)
	if source is not None:
		try:
			url = "https://api.openweathermap.org/data/2.5/weather?id=" + location + "&appid=" + appid + "&lang=" + language + "&units=" + units
			with urllib.request.urlopen(url) as response:
				data = json.loads(response.read().decode())

				temp_main = data['main']['temp']
				temp_max = data['main']['temp_max']
				temp_feels_like = data['main']['feels_like']
				humidity = data['main']['humidity']
				pressure = data['main']['pressure']
				sunrise = datetime.fromtimestamp(data['sys']['sunrise']).strftime('%H:%M')
				sunset = datetime.fromtimestamp(data['sys']['sunset']).strftime('%H:%M')
				description = data['weather'][0]['description']
				wind_speed = data['wind']['speed']
				wind_deg = deg_compass(data['wind']['deg'], language)

				wout = "Currently {}°C {}\nMaximum: {}°F\nHumidity: {}%\nPressure: {} hPa\nSunrise: {}\nSunset: {}\nWind: {} m/s from {}".format(int(temp_main), description, int(temp_max), int(humidity), int(pressure), sunrise, sunset, wind_speed, wind_deg)
				if language == "de":
					wout = "Aktuell {}°C {}\nHöchstwert: {}°C\nLuftfeuchtigkeit: {}%\nLuftdruck: {} hPa\nSonnenaufgang: {} Uhr\nSonnenuntergang: {} Uhr\nWind: {} m/s aus {}".format(int(temp_main), description, int(temp_max), int(humidity), int(pressure), sunrise, sunset, wind_speed, wind_deg)

				#print(wout)

				content = obs.obs_data_create()
				obs.obs_data_set_string(content, "text", wout)
				obs.obs_source_update(source, content)
				obs.obs_data_release(content)

		except urllib.error.URLError as err:
			obs.script_log(obs.LOG_WARNING, "Error opening URL '" + url + "': " + err.reason)
			obs.remove_current_callback()

		obs.obs_source_release(source)

def refresh_pressed(props, prop):
	update_text()

# ------------------------------------------------------------

def deg_compass(deg, lang):
	val = math.floor((deg / 22.5) + 0.5)
	arr = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"]
	if lang == "de":
		arr = ["N", "NNO", "NO", "ONO", "O", "OSO", "SO", "SSO", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"]
	return arr[(val % 16)]

def script_description():
	return "<b>Weather Text</b><br />Populates a text source with current weather data retrieved from OpenWeatherMap.<br /><br /><a href='https://home.openweathermap.org/api_keys'>Create your AppID</a><br /><a href='https://www.openweathermap.org/find?q='>Get location code</a><br /><br />By Pandalorian. Based on url-text.py from Jim."

def script_update(settings):
	global appid
	global location
	global language
	global units
	global url
	global interval
	global source_name

	appid       = obs.obs_data_get_string(settings, "appid")
	location    = obs.obs_data_get_string(settings, "location")
	language    = obs.obs_data_get_string(settings, "language")
	units       = obs.obs_data_get_string(settings, "units")
	url         = obs.obs_data_get_string(settings, "url")
	interval    = obs.obs_data_get_int(settings, "interval")
	source_name = obs.obs_data_get_string(settings, "source")

	obs.timer_remove(update_text)

	if appid != "" and source_name != "":
		obs.timer_add(update_text, interval * 1000)

def script_defaults(settings):
	obs.obs_data_set_default_int(settings, "interval", 30)

def script_properties():
	props = obs.obs_properties_create()

	obs.obs_properties_add_text(props, "appid", "APPID", obs.OBS_TEXT_DEFAULT)
	obs.obs_properties_add_text(props, "location", "LOCATION", obs.OBS_TEXT_DEFAULT)

	l = obs.obs_properties_add_list(props, "language", "Language", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING)
	obs.obs_property_list_add_string(l, "English", "en")
	obs.obs_property_list_add_string(l, "German", "de")

	u = obs.obs_properties_add_list(props, "units", "Units", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING)
	obs.obs_property_list_add_string(u, "Imperial", "imperial")
	obs.obs_property_list_add_string(u, "Metric", "metric")

	obs.obs_properties_add_int(props, "interval", "Update Interval (seconds)", 5, 3600, 1)

	p = obs.obs_properties_add_list(props, "source", "Text Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
	sources = obs.obs_enum_sources()
	if sources is not None:
		for source in sources:
			source_id = obs.obs_source_get_unversioned_id(source)
			if source_id == "text_gdiplus" or source_id == "text_ft2_source":
				name = obs.obs_source_get_name(source)
				obs.obs_property_list_add_string(p, name, name)

		obs.source_list_release(sources)

	obs.obs_properties_add_button(props, "button", "Refresh", refresh_pressed)
	return props
