#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-

__revision__ = '$Id: griffith 106 2005-11-19 12:39:51Z iznogoud $'

# Copyright (c) 2005 Vasco Nunes
# 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 2 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

# You may use and distribute this software under the terms of the
# GNU General Public License, version 2 or later

import sys
import gtk
import os.path
import random
assert gtk.pygtk_version >= (2, 4, 0), \
	'pygtk should be >= 2.4.0' 
import gtk.glade
import about
import gutils
import add
import delete
import update
import loan
import backup
import cover
import preferences
import people
import edit
import version
import initialize
import view
import gdebug
import gemail
import main_treeview
import quick_filter
from gettext import gettext as _

class Griffith:
	"""The main application class"""
   
	Image = gtk.Image()
	founded_results_id = None
	
	def initialize_griffith(self):
		initialize.locations(self) 
		initialize.toolbar(self)
		initialize.treeview(self)
		initialize.loans_treeview(self)
		initialize.combos(self)
		initialize.movie_plugins(self)
		initialize.export_plugins(self)
		initialize.people_treeview(self)
		initialize.web_results(self)
			
	###########
	# callbacks
	###########		
			
	def on_export_activate(self, menu_iter, plugin_name):
		export_plugin = __import__('PluginExport%s' % plugin_name)
		export_plugin.ExportPlugin(self.db, self.locations, self.main_window)

	def destroy(self, widget, data=None):
		self.save_state()
		gtk.main_quit()   
		
	# about dialog				  
		
	def about_dialog(self, *args):
		about_dialog = about.AboutDialog()
		about_dialog.icon = self.locations['images']
			
	# add movie
		
	def clear_add_dialog(self, *args):
		add.initialize_add_dialog(self)
	
	def hide_add_movie(self, *args):
		self.add_movie_window.hide()
		
	def hide_add(self, *args):
		self.add_movie_window.hide()
		
	def get_from_web(self, *args):
		add.get_from_web(self)
		
	def show_search_results(self, results):
		add.show_websearch_results(self)
		
	def hide_results(self, *args):
		self.treemodel_results.clear()
		try:
			self.results_select.disconnect(self.poster_results_signal)
			self.results_signal = self.results_select.connect("clicked", \
				self.populate_dialog_with_results)
		except:
			pass
		self.w_results.hide()
		
	def populate_dialog_with_results(self, *args):
		add.populate_with_results(self) 
		
	def source_changed(self, *args):
		add.source_changed(self)
		
	# preferences
		
	def show_preferences(self, *args):
		preferences.show_preferences(self)
		
	def hide_preferences(self, *args):
		self.w_preferences.hide()
		
	def save_preferences(self, *args):
		preferences.save_preferences(self)
		self.hide_preferences()
		
	# movie operations related 
		
	def add_movie(self, *args):
		add.add_movie(self)
		
	def add_movie_db(self, *args):
		add.add_movie_db(self, 0)
		
	def add_movie_close_db(self, *args):
		add.add_movie_db(self, 1)
		
	def delete_movie(self, *args):
		delete.delete_movie(self)
		
	def delete_movie_from_db(self, *args):
		delete.delete_movie_from_db(self)
		
	def update_movie(self, *args):
		update.update(self) 
		
	def clear_details(self):
		edit.clear_details(self)
   
	def go_first(self, *args):
		if self.total_filter:
			self.main_treeview.set_cursor_on_cell(0)	
			self.treeview_clicked()
		
	def go_last(self, *args):
		if self.total_filter:
			self.main_treeview.set_cursor_on_cell(self.total_filter-1)  
			self.treeview_clicked()  
			
	def loan_movie(self, *args):
		loan.loan_movie(self)		
		
	def clone_movie(self, *args):
		add.clone_movie(self)	
		
	# poster	
		   
	def change_poster(self, *args):
		edit.change_poster(self)
		
	def del_poster(self, *args):
		edit.delete_poster(self)
		
	def z_poster(self, *args):
		treeselection = self.main_treeview.get_selection()
		(tmp_model, tmp_iter) = treeselection.get_selected()
		id = tmp_model.get_value(tmp_iter, 1)
		data = self.db.select_movie_by_num(id)
		for row in data:
			if row['image']:
				tmp_dest = os.path.join(self.griffith_dir, "posters")
				tmp_img = os.path.join(tmp_dest, row['image']+".jpg")
				self.big_poster.set_from_file(tmp_img)
				self.poster_window.show()
				
	def z_poster_hide(self, *args):
		self.poster_window.hide()
			
	def get_poster(self, *args):
		"""tries to fetch a new big poster from amazon"""
		edit.fetch_bigger_poster(self)
		
	# rating
		
	def scale_rating_change(self, *args):
		edit.change_rating_from_slider(self)

	def scale_rating_change_add(self, *args):
		add.change_rating_from_slider(self)
		
	def toggle_seen(self, *args):
		edit.toggle_seen(self)
		
	def sugest_movie(self, *args):
		quick_filter.change_filter(self)		
		subtotal = self.db.count_records('movies','seen=0')
		self.clear_filter()
		self.all_movies.set_active(1)
		self.count_statusbar()
		if subtotal > 0:
			data = self.db.get_not_seen_movies()
			sugested_movie = data[random.randrange(subtotal)]
			gdebug.debug("suggested movie: %s"%sugested_movie['title'])			
			self.main_treeview.set_cursor_on_cell(sugested_movie['number']-1)	
			self.treeview_clicked()
		else:
			gutils.info(self, \
				self._("You saw all movies in your collection!"), \
				self.main_window)

	# volumes/collections			
	
	def add_volume(self, widget):
		prefix = gutils.before(widget.get_name(), "_")
		try:
			id = int(eval("self.%s_volume_id.get_text()"%prefix))
		except:
			id = 0
		name = eval("self.%s_volume_combo.get_active_text()"%prefix)
		self.db.add_volume(name)
		edit.fill_volumes_combo(self, prefix, id)

	def add_collection(self, widget):
		prefix = gutils.before(widget.get_name(), "_")
		try:
			id = int(eval("self.%s_collection_id.get_text()"%prefix))
		except:
			id = 0
		name = eval("self.%s_collection_combo.get_active_text()"%prefix)
		self.db.add_collection(name)
		edit.fill_collections_combo(self, prefix, id)

	def remove_volume(self, widget):
		prefix = gutils.before(widget.get_name(), "_")
		try:
			id = int(eval("self.%s_volume_id.get_text()"%prefix))
		except:
			id = 0
		name = eval("self.%s_volume_combo.get_active_text()"%prefix)
		self.db.remove_volume(name=name)
		edit.fill_volumes_combo(self, prefix, id)

	def remove_collection(self, widget):
		prefix = gutils.before(widget.get_name(), "_")
		try:
			id = int(eval("self.%s_collection_id.get_text()"%prefix))
		except:
			id = 0
		name = eval("self.%s_collection_combo.get_active_text()"%prefix)
		self.db.remove_collection(name=name)
		edit.fill_collections_combo(self, prefix, id)

	def e_rename_volume(self, widget):
		id = self.e_volume_id.get_text()
		new_name = self.e_volume_combo.get_active_text()
		update.update_volume(self, id, name=new_name)
		edit.fill_volumes_combo(self, prefix='e', default=id)

	def e_rename_collection(self, widget):
		id = self.e_collection_id.get_text()
		new_name = self.e_collection_combo.get_active_text()
		update.update_collection(self, id, name=new_name)
		edit.fill_collections_combo(self, prefix='e', default=id)

	def e_show_volume(self, widget):
		volume_id = self.e_volume_combo.get_active()
		if volume_id == 0:
			view.filter_all(self)
		else:
			view.filter_by_volume(self, volume_id)

	def e_show_collection(self, widget):
		collection_id = self.e_collection_combo.get_active()
		if collection_id == 0:
			view.filter_all(self)
		else:
			view.filter_by_collection(self, collection_id)

	# main treeview
	def treeview_clicked(self, *args):
		main_treeview.treeview_clicked(self)				 
					
	def populate_treeview(self, data):
		main_treeview.populate(self, data)
		
	def get_maintree_selection(self):
		treeselection = self.main_treeview.get_selection()
		(tmp_model, tmp_iter) = treeselection.get_selected()
		return tmp_model.get_value(tmp_iter, 1), tmp_iter
		
	def select_last_row(self, rtotal):
		if rtotal:
			self.main_treeview.set_cursor_on_cell(rtotal-1)	
			self.treeview_clicked()						
		
	# backup/restore		
		
	def backup(self, *args):
		backup.backup(self)
		
	def restore(self, *args):
		response = gutils.question(self, \
			self._("Are you sure you want to restore?\n" \
			+ "Your current movie collection will be replaced.\n" \
			+ "You can't undo this operation."), \
			1, self.main_window)
		if response == gtk.RESPONSE_YES:
			backup.restore(self)
		else:
			pass
			
	# cover
			
	def print_cover_simple_show(self, *args):
		self.cover_simple_size.set_active(0)
		self.w_print_cover_simple.show()
		
	def print_cover_simple_hide(self, *args):
		self.w_print_cover_simple.hide()
		
	def print_cover_simple_process(self, *args):
		movie_id, movie_iter = self.get_maintree_selection()
		cover.cover_simple(self, movie_id)
		
	def print_cover_image(self, *args):
		self.cover_image_size.set_active(0)
		self.w_print_cover_image.show()
		
	def print_cover_image_process(self, *args):
		self.w_print_cover_image.hide()
		movie_id, movie_iter = self.get_maintree_selection()
		cover.cover_image(self, movie_id)
		
	def print_cover_image_hide(self, *args):
		self.w_print_cover_image.hide()
		
	# loans management		
		
	def show_people_window(self, *args):
		people.show_people_window(self)
		
	def hide_people_window(self, *args):
		people.hide_people_window(self)
		
	def add_person(self, *args):
		people.add_person(self)
		
	def add_person_cancel(self, *args):
		people.add_person_cancel(self)
	
	def add_person_db(self, *args):
		people.add_person_db(self)
		
	def delete_person(self, *args):
		people.delete_person(self)
		
	def edit_person(self, *args):
		people.edit_person(self)
		
	def update_person(self, *args):
		people.update_person(self)
		
	def edit_person_cancel(self, *args):
		people.edit_person_cancel(self)
		
	def cancel_loan(self, *args):
		loan.cancel_loan(self)

	def commit_loan(self, *args):
		loan.commit_loan(self)
		
	def return_loan(self, *args):
		loan.return_loan(self)
		
	def email_reminder(self, *args):
		gemail.send_email(self)
		
	# statusbar
		
	def count_statusbar(self):
		text = str(self.total)
		loaned = self.db.count_records('movies','loaned=1')
		not_seen = self.db.count_records('movies','seen=0')
		self.update_statusbar(str(text) + self._(' movie(s) in collection. ')
			+ str(loaned) + self._(' movie(s) loaned. ')
			+ self._('You haven\'t seen ')+"%s"%str(not_seen)+" movie(s)"
		)
		
	def update_statusbar(self, text):
		context_id = self.statusbar.get_context_id(text)
		message_id = self.statusbar.push(context_id, text)
		
	# quick filter operations
		
	def filter_txt(self, *args):
		quick_filter.change_filter(self)
		
	def clear_filter(self, *args):
		quick_filter.clear_filter(self)
	   
	# menu filter

	def filter_loaned(self, *args):
		view.filter_loaned(self)
		
	def filter_not_seen(self, *args):
		view.filter_not_seen(self)
		
	def filter_all(self, *args):
		view.filter_all(self)
		
	def on_delete_event_am(self, *args):
		self.add_movie_window.hide()
		return True
		
	def on_delete_event_pw(self, *args):
		self.poster_window.hide()
		return True
		
	def filter_collection(self, *args):
		collection_id = self.f_col.get_active()
		if collection_id == 0:
			view.filter_all(self)
		else:
			view.filter_by_collection(self, collection_id)
   
	# windows/dialogs  
	
	def results_cancel_ck(self, *args):
		self.w_results.hide() 
   
	def save_state(self):
		"""Saves main window state"""
		pos = self.main_window.get_position()
		size = self.main_window.get_size()
		self.config["width"] = size[0]
		self.config["height"] = size[1]
		self.config["left"] = pos[0]	  
		self.config["top"] = pos[1]
		self.config.save()
		
	def restore_state(self):
		"""Restores main window state"""
		if self.config.get("left") == "None":
			pass
		else:
			self.main_window.move(int(self.config.get("left")), \
				int(self.config.get("top")))
			self.main_window.resize(int(self.config.get("width")), \
				int(self.config.get("height"))) 
		self.main_window.show()  
   
	def on_delete_event_r(self, *args):
		self.w_results.hide()
		return True
		
	def on_delete_event_poster(self, *args):
		self.poster_window.hide()
		return True
		   
	def on_delete_event_wp(self, *args):
		self.w_people.hide()
		return True		
		   
	def on_delete_event_ap(self, *args):
		self.w_add_person.hide()
		return True		   
		   
	def on_delete_event_ep(self, *args):
		self.w_edit_person.hide()
		return True
		   
	def on_delete_event_lt(self, *args):
		self.w_loan_to.hide()
		return True
		   
	def on_delete_event_pcs(self, *args):
		self.w_print_cover_simple.hide()
		return True
		   
	def on_delete_event_pci(self, *args):
		self.w_print_cover_image.hide()
		return True
		   
	def on_delete_event_p(self, *args):
		self.w_preferences.hide()
		return True 
		   
	def go_oficial_site(self, *args):
		if self.e_site.get_text():
			gutils.run_browser(self.e_site.get_text())

	def go_imdb_site(self, *args):
		if self.e_imdb.get_text():
			gutils.run_browser(self.e_imdb.get_text())

	def go_trailer_site(self, *args):
		if self.e_trailer.get_text():
			gutils.run_browser(self.e_trailer.get_text())

	# toolbar
	
	def toggle_toolbar(self, *args):
		state = self.menu_toolbar.get_active()
		if state == False:
			self.toolbar.hide()
		else:
			self.toolbar.show()
		self.config["view_toolbar"] = state
		self.config.save()										 
	
	def new_dbb(self, *args):
		self.db.new_db(self)
			
	# key events
			
	def on_key_press_event(self, widget, event):
		"""some key events actions"""
		keyname = gtk.gdk.keyval_name(event.keyval)
		if keyname == 'Delete' and self.main_treeview.is_focus() == True:
			self.delete_movie() 
			
	def on_p_tree_button_press_event(self, widget, event): 
		"""add a double click event to people tree"""				
		if event.type == gtk.gdk._2BUTTON_PRESS:
			people.edit_person(self)

	def on_maintree_button_press_event(self, widget, event):
		"""add a left click menu to main tree"""				
		if event.button == 3:
			x = int(event.x)
			y = int(event.y)
			time = event.time
			pthinfo = self.main_treeview.get_path_at_pos(x, y)
			if pthinfo != None:
				path, col, cellx, celly = pthinfo
				self.main_treeview.grab_focus()
				self.main_treeview.set_cursor( path, col, 0)
				self.popup.popup( None, None, None, event.button, time)
			return 1
			
	def on_results_button_press_event(self, widget, event):  
		"""add a double click event to add movie results"""
		if event.type == gtk.gdk._2BUTTON_PRESS:
			add.populate_with_results(self)
			
	def on_poster_results_button_press_event(self, widget, event):  
		"""add a double click event to poster results"""
		if event.type == gtk.gdk._2BUTTON_PRESS:
			add.populate_with_results(self)
							  
	def __init__(self):
		"""
		main griffith application constructor
		"""
		self.args = map(lambda i: i.replace('--', '').replace('-',''), sys.argv)
		
		if 'version' in self.args:
			print "Griffith version %s" % version.pversion
			sys.exit()			
			
		gtk.window_set_auto_startup_notification(True)
		self.Image = gtk.Image()
		self.filter_l = False
		self.loans_treemodel = gtk.TreeStore(str, str, str)
		self.initialize_griffith()
		self.restore_state()
		self.clear_details()
		self.count_statusbar()
		self.filter_criteria.set_active(1)
		self.select_last_row(self.total)

		# adding some completion fields
		
		self.completion = gtk.EntryCompletion()
		self.am_original_title.set_completion(self.completion)
		self.completion.set_model(self.treemodel)
		self.completion.set_text_column(3)
		self.completion_t = gtk.EntryCompletion()
		self.am_title.set_completion(self.completion_t)
		self.completion_t.set_model(self.treemodel)
		self.completion_t.set_text_column(4)
				
		initialize.initialize_gtkspell(self)
		
	def main(self):
		gtk.threads_init()
		gtk.threads_enter()
		gtk.main()
		gtk.threads_leave()
		return 0
		
if __name__ == "__main__":
	# Import Psyco if available
	try:
		#import psyco
		#psyco.profile()
		gdebug.debug("Psyco module detected and being used.")
	except ImportError:
		pass
	griffith = Griffith()
	griffith.main()
