#!/usr/bin/python

# This is a part of the external Moon applet for Cairo-Dock
#
# Author: Eduardo Mucelli Rezende Oliveira
# E-mail: edumucelli@gmail.com or eduardom@dcc.ufmg.br
#
# This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.

# This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#	GNU General Public License for more details.

# This applet displays the moon phases and its informations for the current day or week
# from the Northern or Southern hemisphere

import datetime, os, re
from sgmllib import SGMLParser
try: # python 3
	from urllib.parse import urlencode
	from urllib.request import FancyURLopener
except: # python 2
	from urllib import urlencode
	from urllib import FancyURLopener

from util import log
from CDApplet import CDApplet, _

from MoonCalendarParser import MoonCalendarParser

class AgentOpener(FancyURLopener):
	"""Masked user-agent otherwise the access would be forbidden"""
	version = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11'

class Interface:

	def __init__(self, year, month, day):
		self.year, self.month, self.day = year, month, day
		self.information = ""
		self.moon_image = ""

	def fetch(self):
		parser = MoonCalendarParser()
		opener = AgentOpener()													  	# opens the web connection with masked user-agent
		params = urlencode({'year': self.year, 'month': self.month, 'day': self.day})
		
		try:
			page = opener.open(parser.url, params)
		except IOError:
			log("Problem to open %s" % (parser.url))
		else:
			parser.parse(str(page.read()))										   	# feed the parser to get the specific content: translated text
			page.close()															# lets close the page connection
			self.information = parser.information
			self.moon_image = parser.moon_image
		return self.moon_image, self.information

class Applet(CDApplet):

	def inform_start_of_waiting_process(self):
		self.icon.SetQuickInfo("...")

	def inform_end_of_waiting_process(self):
		self.icon.SetQuickInfo("")

	def flatten(self, array):														# Ruby method :-)
		return [item for sublist in array for item in sublist]
	
	def clean(self, string):
		return re.sub("\s+\n\s+" , " \n", string)									# " ".join(information.split())
	
	def clean_week_icons(self):
		self.sub_icons.RemoveSubIcon("any")

	def name_of_the_day(self, day):
		days = [_('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday'), _('Sunday')]
		return days[datetime.date.weekday(day)]

	def img_local_path(self, image):
		for ext in ['gif', 'svg', 'png', 'jpg', 'jpeg']:
			img_file = os.path.abspath("./data/%s.%s" % (image, ext))
			if os.path.exists (img_file):
				return img_file
		return os.path.abspath("./data/%s.gif" % image)

	def get_info_image_today (self, today):
		ye, mo, da = today.timetuple()[:3]
		interface = Interface(ye, mo, da)
		image, information = interface.fetch()
		return image, self.clean(information)

	def get_moon_from_web(self):
		self.inform_start_of_waiting_process()

		self.clean_week_icons()
		today = datetime.date.today()
		if self.show_week_moon:														# week information
			tomorrow = datetime.timedelta(days=1)
			last_day = datetime.date.today() + datetime.timedelta(days=6)
			week = []																# ['namesubicon1','imagesubicon1','idsubicon1', 'namesubicon2' ...]
			self.week_information = []
			id = 0
			while today <= last_day:
				image, information = self.get_info_image_today(today)
				if id == 0:
					self.icon.SetIcon(self.img_local_path(image)) # main icon

				# The website provides images from the Northern perspective, but since
				# a) The images differs horizontally by "a", or "b" in its names;
				# b) The moon differs horizontally between hemispheres;
				# It is just a question of replace "a" (North) by "b" (South)
				if self.hemisphere == self.south:
					image = image.replace('a','b')
				self.week_information.append(information)
				week.append(self.name_of_the_day(today))
				week.append(self.img_local_path(image))
				week.append(str(id))												# id is a sequential from today (0) until end of the week (6)
				id += 1
				today += tomorrow
			# log(week)
			self.sub_icons.AddSubIcons(week)
		else:																		# todays information
			image, self.information = self.get_info_image_today(today)
			self.icon.SetIcon(self.img_local_path(image))

		self.inform_end_of_waiting_process()

	def __init__(self):

		self.show_week_moon = False
		self.north, self.south = list(range(2))
		self.hemisphere = self.north
		self.information = ""
		self.week_information = []
		self.dialog_active_time = 30												# time in seconds that the dialog window will be active

		CDApplet.__init__(self)														# call high-level init

	# Inherited methods from CDApplet
	def begin(self):
		self.get_moon_from_web()

	def get_config(self, keyfile):
		self.show_week_moon = keyfile.getboolean('Configuration', 'week')			# information from the current day or from the whole week
		self.hemisphere = keyfile.getboolean('Configuration', 'hemisphere')			# view from the north, or south hemisphere

	def reload(self):
		self.get_moon_from_web()													# refresh the moon informations

	# Callbacks
	def on_click(self, key):
		if not self.show_week_moon:													# avoid useless popup
			self.icon.PopupDialog({'message':self.information, 'time-length':self.dialog_active_time},{})
	
	def on_click_sub_icon (self, state, sub_icon_id):
		self.icon.PopupDialog({'message':self.week_information[int(sub_icon_id)], 'time-length':self.dialog_active_time},{})

if __name__ == '__main__':
	Applet().run()
