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

__revision__ = '$Id: griffith 305 2006-04-11 13:37:11Z piotrek $'

# Copyright (c) 2005-2006 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
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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
import gconsole
import sql
import config
import gglobals
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.dictionaries(self)
		initialize.combos(self)
		initialize.movie_plugins(self)
		initialize.export_plugins(self)
		initialize.people_treeview(self)
		initialize.web_results(self)
		self.initialized = 1

	###########
	# 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, self.debug)

	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)
		
	def go_last(self, *args):
		if self.total_filter:
			self.main_treeview.set_cursor_on_cell(self.total_filter-1)
			
	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)]
			self.debug.show("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)
		update.update_volume_combo_ids(self)
		initialize.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)
		update.update_collection_combo_ids(self)
		initialize.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)
		update.update_volume_combo_ids(self)
		initialize.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)
		update.update_collection_combo_ids(self)
		initialize.fill_collections_combo(self, prefix, id)

	def e_rename_volume(self, widget):
		id = self.e_volume_id.get_text()
		if id != 0:
			new_name = self.e_volume_combo.get_active_text()
			if self.db.update_volume(id, name=new_name):
				initialize.fill_volumes_combo(self, prefix='e', default=id)

	def e_rename_collection(self, widget):
		id = self.e_collection_id.get_text()
		if id != 0:
			new_name = self.e_collection_combo.get_active_text()
			if self.db.update_collection(id, name=new_name):
				initialize.fill_collections_combo(self, prefix='e', default=id)

	def e_show_volume(self, widget):
		id = self.volume_combo_ids[self.e_volume_combo.get_active()]
		if id == 0:
			view.filter_all(self)
		else:
			view.filter_by_volume(self, id)

	def e_show_collection(self, widget):
		id = self.collection_combo_ids[self.e_collection_combo.get_active()]
		if id == 0:
			view.filter_all(self)
		else:
			view.filter_by_collection(self, id)
	#}}}

	# languages -------------------------------------------------------{{{
	def on_lang_add_clicked(self, widget):
		name = self.lang_name_combo.get_active_text()
		self.db.add_language(name)
		update.update_language_ids(self)
		initialize.fill_preferences_languages_combo(self)

	def on_lang_remove_clicked(self, widget):
		active = self.lang_name_combo.get_active()
		if active>0:
			id = self.languages_ids[active]
			self.db.remove_language(id=id)
			update.update_language_ids(self)
			initialize.fill_preferences_languages_combo(self)
		else:
			self.debug.show("You have to select language first")

	def on_lang_rename_clicked(self, widget):
		try:
			active = self.lang_name_active
		except:
			return False
		id = self.languages_ids[active]
		if id>0:
			new_name = self.lang_name_combo.get_active_text()
			if self.db.update_language(id=id, name=new_name):
				initialize.fill_preferences_languages_combo(self)

	def on_lang_name_combo_changed(self, widget):
		active = self.lang_name_combo.get_active()
		if active>-1:
			self.lang_name_active = active

	def on_e_lang_add_clicked(self, widget):
		initialize.create_language_hbox(self, widget=self.e_lang_vbox, tab=self.e_languages)
	def on_e_lang_remove_clicked(self, widget):
		initialize.remove_hbox(self, widget=self.e_lang_vbox, tab=self.e_languages)
	def on_am_lang_add_clicked(self, widget):
		initialize.create_language_hbox(self, widget=self.am_lang_vbox, tab=self.am_languages)
	def on_am_lang_remove_clicked(self, widget):
		initialize.remove_hbox(self, widget=self.am_lang_vbox, tab=self.am_languages)
	#}}}

	# tags -------------------------------------------------------------{{{
	def on_tag_add_clicked(self, widget):
		name = self.tag_name_combo.get_active_text()
		self.db.add_tag(name)
		update.update_tag_ids(self)
		initialize.fill_preferences_tags_combo(self)
		initialize.create_tag_vbox(self, widget=self.e_tag_vbox, tab=self.e_tags)
		initialize.create_tag_vbox(self, widget=self.am_tag_vbox, tab=self.am_tags)

	def on_tag_remove_clicked(self, widget):
		active = self.tag_name_combo.get_active()
		if active>-1:
			id = self.tags_ids[active]
			self.db.remove_tag(id=id)
			update.update_tag_ids(self)
			initialize.fill_preferences_tags_combo(self)
			initialize.create_tag_vbox(self, widget=self.e_tag_vbox, tab=self.e_tags)
			initialize.create_tag_vbox(self, widget=self.am_tag_vbox, tab=self.am_tags)
		else:
			self.debug.show("You have to select tag first")

	def on_tag_rename_clicked(self, widget):
		try:
			active = self.tag_name_active
		except:
			return False
		id = self.tags_ids[active]
		new_name = self.tag_name_combo.get_active_text()
		if self.db.update_tag(id=id, name=new_name):
			initialize.fill_preferences_tags_combo(self)
			initialize.create_tag_vbox(self, widget=self.e_tag_vbox, tab=self.e_tags)
			initialize.create_tag_vbox(self, widget=self.am_tag_vbox, tab=self.am_tags)

	def on_tag_name_combo_changed(self, widget):
		active = self.tag_name_combo.get_active()
		if active>-1:
			self.tag_name_active = active
	# }}}

	# 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)

	# 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?
Your current movie collection will be replaced.
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):
		quick_filter.change_filter(self)

	# 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())

	def on_goto_homepage_activate(site, *args):
		gutils.run_browser("http://griffith.vasconunes.net/")
	def on_goto_forum_activate(site, *args):
		gutils.run_browser("http://griffith.vasconunes.net/forum/")
	def on_goto_report_bug_activate(site, *args):
		gutils.run_browser("http://developer.berlios.de/bugs/?group_id=4891")

	# 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
		"""

		# debug object
		self.debug = gdebug.GriffithDebug()
		# Configuration
		self.config = config.Config()
		# create/connect db
		self.db = sql.GriffithSQL(self.config, self.debug, gglobals.griffith_dir)

		# let's check any console arguments to parse
		gconsole.check_args(self)

		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.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)

		# add default folders to some select widgets

		if self.windows:
			self.p_font.set_current_folder("c:\\windows\\fonts\\")
		else:
			self.p_font.set_current_folder("/usr/share/fonts/")

	def main(self):
		gtk.gdk.threads_init()
		gtk.gdk.threads_enter()
		gtk.main()
		gtk.gdk.threads_leave()
		return 0

if __name__ == "__main__":
	griffith = Griffith()
	griffith.main()

#vim: fdm=marker
