#
# FtpCube
# Copyright (C) 2001 Michael Gilfix
#
# This file is part of FtpCube.
#
# You should have received a file COPYING containing license terms
# along with this program; if not, write to Michael Gilfix
# (mgilfix@eecs.tufts.edu) for a copy.
#
# This version of FtpCube is open source; you can redistribute it and/or
# modify it under the terms listed in the file COPYING.
#
# 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.
#

import gtk
import sys, os
import main

from intl import _

# For compatibility with win32 pygtk
if sys.platform == "win32":
	import GTKconst
	GTK = GTKconst
else:
	import GTK

class OptionWindow:

	def __init__ (self):

		self.opts = main.app.load_config (main.app.get_config_file ())

		self.dialog = gtk.GtkDialog ()
		self.dialog.set_title (_("ftpcube - Options"))
		self.dialog.set_policy (gtk.FALSE, gtk.FALSE, gtk.TRUE)
		self.dialog.set_position (gtk.WIN_POS_CENTER)
		icon_pic, icon_mask = gtk.create_pixmap_from_xpm (self.dialog, None, os.path.join (main.ICONS_PREFIX, "ftpcube.xpm"))
		self.dialog.set_icon (gtk.GtkPixmap (icon_pic, icon_mask))

		# Make ourselves modal
		gtk.grab_add (self.dialog)

		packer = gtk.GtkPacker ()
		packer.show ()
		self.dialog.action_area.add (packer)
		table = gtk.GtkTable (2, 1)
		table.set_col_spacing (0, 100)
		table.show ()
		packer.add (table)

		button = gtk.GtkButton (_("Accept"))
		button.set_usize (50, 25)
		button.connect ("clicked", self.accept)
		table.attach (button, 0, 1, 0, 1, xoptions=GTK.EXPAND)
		button.show ()

		button = gtk.GtkButton (_("Cancel"))
		button.set_usize (50, 25)
		button.connect ("clicked", self.cancel)
		table.attach (button, 1, 2, 0, 1, xoptions=GTK.EXPAND)
		button.show ()

		self.notebook = gtk.GtkNotebook ()
		self.notebook.set_tab_pos (gtk.POS_TOP)
		self.dialog.vbox.add (self.notebook)
		self.notebook.show ()

		# Create the tabs and add them and show them
		self.connection_tab = ConnectionTab (self.opts)
		label = gtk.GtkLabel (_("Connections"))
		label.set_padding (2, 2)
		label.show ()
		self.notebook.append_page (self.connection_tab.get_page (), label)

		self.logging_tab = LoggingTab (self.opts)
		label = gtk.GtkLabel (_("Logging"))
		label.set_padding (2, 2)
		label.show ()
		self.notebook.append_page (self.logging_tab.get_page (), label)

		self.colors_tab = ColorsTab (self.opts)
		label = gtk.GtkLabel (_("Colors"))
		label.set_padding (2, 2)
		label.show ()
		self.notebook.append_page (self.colors_tab.get_page (), label)

#		self.external_tab = ExternalTab (self.opts)
#		label = gtk.GtkLabel (_("Externals"))
#		label.set_padding (2, 2)
#		label.show ()
#		self.notebook.append_page (self.external_tab.get_page (), label)
#
		self.dialog.show ()

	def accept (self, button):

		# Need to do this to make sure the current color is saved
		self.colors_tab.save_current_color ()

		options = self.get_options ()
		self.opts.update (options)
		main.app.save_config (main.app.get_config_file (), self.opts)
		main.app.update (self.opts)

		# Set the logging parameter for each active thread in case it
		# changed
		for thread in main.app.get_thread_list ():
			thread.set_log_active (self.opts['logging'])

		self.cancel (button)

	def cancel (self, button):

		self.dialog.hide ()
		self.dialog.destroy ()

	def get_options (self):

		opts = { }
		opts.update (self.connection_tab.get_options ())
		opts.update (self.logging_tab.get_options ())
		opts.update (self.colors_tab.get_options ())
		#opts.update (self.external_tab.get_options ())
		return opts

class ConnectionTab:

	def __init__ (self, opts):

		self.page = gtk.GtkFrame (_("Default Connection Settings"))
		self.page.set_border_width (10)
		self.page.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		self.page.show ()

		vbox = gtk.GtkVBox ()
		vbox.show ()
		self.page.add (vbox)

		frame = gtk.GtkFrame (_("Log Files"))
		frame.set_border_width (10)
		frame.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		frame.show ()
		vbox.pack_start (frame, expand=GTK.FALSE)
		packer = gtk.GtkPacker ()
		packer.show ()
		frame.add (packer)
		table = gtk.GtkTable (3, 4)
		table.set_row_spacings (7)
		table.show ()
		packer.add (table, options=GTK.FILL_X+GTK.FILL_Y, pad_x=15, pad_y=15)

		# Create the timeout slot
		label = gtk.GtkLabel (_("Connection timeout:"))
		label.show ()
		table.attach (label, 0, 1, 0, 1)
		self.timeout = gtk.GtkEntry ()
		if opts is not None and opts['timeout']:
			self.timeout.set_text ("%s" %opts['timeout'])
		self.timeout.show ()
		table.attach (self.timeout, 1, 2, 0, 1)
		label = gtk.GtkLabel (_("(seconds)"))
		label.show ()
		table.attach (label, 2, 3, 0, 1)

		label = gtk.GtkLabel (_("Idle Timeout:"))
		label.show ()
		table.attach (label, 0, 1, 1, 2)
		self.main_idle = gtk.GtkEntry ()
		if opts is not None and opts['main_idle']:
			self.main_idle.set_text ("%s" %opts['main_idle'])
		self.main_idle.show ()
		table.attach (self.main_idle, 1, 2, 1, 2)
		label = gtk.GtkLabel (_("(seconds)"))
		label.show ()
		table.attach (label, 2, 3, 1, 2)

		# Create the delay slot
		label = gtk.GtkLabel (_("Delay between retries:"))
		label.show ()
		table.attach (label, 0, 1, 2, 3)
		self.delay = gtk.GtkEntry ()
		if opts is not None and opts['delay']:
			self.delay.set_text ("%s" %opts['delay'])
		self.delay.show ()
		table.attach (self.delay, 1, 2, 2, 3)
		label = gtk.GtkLabel (_("(seconds)"))
		label.show ()
		table.attach (label, 2, 3, 2, 3)

		# Create the retries slot
		label = gtk.GtkLabel (_("Number of attempts:"))
		label.show ()
		table.attach (label, 0, 1, 3, 4)
		self.retries = gtk.GtkEntry ()
		if opts is not None and opts['retries']:
			self.retries.set_text ("%s" %opts['retries'])
		self.retries.show ()
		table.attach (self.retries, 1, 2, 3, 4)

		# Create the thread options frame
		frame = gtk.GtkFrame (_("Thread options"))
		frame.set_border_width (10)
		frame.set_shadow_type (GTK.SHADOW_ETCHED_OUT)
		frame.show ()
		vbox.pack_start (frame, expand=GTK.FALSE)
		packer = gtk.GtkPacker ()
		packer.show ()
		frame.add (packer)
		table = gtk.GtkTable (3, 1)
		table.show ()
		packer.add (table, options=GTK.FILL_X+GTK.FILL_Y, pad_x=15, pad_y=15)

		# Create the idle slot
		label = gtk.GtkLabel (_("Idle timeout for threads:"))
		label.show ()
		table.attach (label, 0, 1, 0, 1)
		self.thread_idle = gtk.GtkEntry ()
		self.thread_idle.set_usize (40, -1)
		if opts is not None and opts['thread_idle']:
			self.thread_idle.set_text ("%s" %opts['thread_idle'])
		self.thread_idle.show ()
		table.attach (self.thread_idle, 1, 2, 0, 1)
		label = gtk.GtkLabel (_("(seconds)"))
		label.show ()
		table.attach (label, 2, 3, 0, 1)

	def get_options (self):

		opts = { }
		if self.timeout.get_text ():
			opts['timeout'] = int (self.timeout.get_text ())
		if self.main_idle.get_text ():
			opts['main_idle'] = int (self.main_idle.get_text ())
		if self.delay.get_text ():
			opts['delay'] = int (self.delay.get_text ())
		if self.retries.get_text ():
			opts['retries'] = int (self.retries.get_text ())
		if self.thread_idle.get_text ():
			opts['thread_idle'] = int (self.thread_idle.get_text ())
		return opts

	def get_page (self):
		return self.page

class LoggingTab:

	def __init__ (self, opts):

		# Create instance variables
		self.log = 0

		self.page = gtk.GtkFrame (_("FTP Logging"))
		self.page.set_border_width (10)
		self.page.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		self.page.show ()

		vbox = gtk.GtkVBox ()
		vbox.show ()
		self.page.add (vbox)

		frame = gtk.GtkFrame (_("Activate Logging"))
		frame.set_border_width (10)
		frame.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		frame.show ()
		vbox.pack_start (frame, expand=GTK.FALSE)
		table = gtk.GtkTable (2, 1)
		table.show ()
		frame.add (table)

		self.activate_button = gtk.GtkRadioButton (None, _("Turn ON Logging"))
		self.activate_button.connect ("clicked", self.activate_clicked)
		self.activate_button.show ()
		self.deactivate_button = gtk.GtkRadioButton (self.activate_button, _("Turn OFF Logging"))
		self.deactivate_button.connect ("clicked", self.deactivate_clicked)
		self.deactivate_button.show ()
		if opts is not None:
			if int (opts['logging']):
				self.activate_button.set_active (gtk.TRUE)
			else:
				self.deactivate_button.set_active (gtk.TRUE)
		packer = gtk.GtkPacker ()
		packer.show ()
		packer.add (self.activate_button)
		table.attach (packer, 0, 1, 0, 1, ypadding=4)
		packer = gtk.GtkPacker ()
		packer.show ()
		packer.add (self.deactivate_button)
		table.attach (packer, 1, 2, 0, 1, ypadding=4)

		packer = gtk.GtkPacker ()
		packer.show ()
		vbox.pack_start (packer)
		frame = gtk.GtkFrame (_("Log Files"))
		frame.set_border_width (10)
		frame.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		frame.show ()
		packer.add (frame, options=GTK.FILL_X)
		packer = gtk.GtkPacker ()
		packer.show ()
		frame.add (packer)
		table = gtk.GtkTable (2, 3)
		table.set_row_spacings (7)
		table.show ()
		packer.add (table, options=GTK.FILL_X+GTK.FILL_Y, pad_x=25, pad_y=25)

		label = gtk.GtkLabel (_("FTP command log:"))
		label.show ()
		self.cmds = gtk.GtkEntry ()
		if opts is not None and opts['cmd_log']:
			self.cmds.set_text (opts['cmd_log'])
		self.cmds.show ()
		table.attach (label, 0, 1, 0, 1)
		table.attach (self.cmds, 1, 2, 0, 1)

		label = gtk.GtkLabel (_("Download log:"))
		label.show ()
		self.downloads = gtk.GtkEntry ()
		if opts is not None and opts['download_log']:
			self.downloads.set_text (opts['download_log'])
		self.downloads.show ()
		table.attach (label, 0, 1, 1, 2)
		table.attach (self.downloads, 1, 2, 1, 2)

		label = gtk.GtkLabel (_("Upload log:"))
		label.show ()
		self.uploads = gtk.GtkEntry ()
		if opts is not None and opts['upload_log']:
			self.uploads.set_text (opts['upload_log'])
		self.uploads.show ()
		table.attach (label, 0, 1, 2, 3)
		table.attach (self.uploads, 1, 2, 2, 3)

	def activate_clicked (self, button):
		self.log = 1

	def deactivate_clicked (self, button):
		self.log = 0

	def get_page (self):
		return self.page

	def get_options (self):

		return {
			'logging' : self.log,
			'cmd_log' : self.cmds.get_text (),
			'download_log' : self.downloads.get_text (),
			'upload_log'   : self.uploads.get_text (),
		}

class ColorsTab:

	def __init__ (self, opts):

		self.page = gtk.GtkFrame (_("Colors"))
		self.page.set_border_width (10)
		self.page.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		self.page.show ()

		vbox = gtk.GtkVBox ()
		vbox.show ()
		self.page.add (vbox)
		self.color_select = gtk.GtkColorSelection ()
		self.color_select.show ()
		vbox.pack_start (self.color_select)

		packer = gtk.GtkPacker ()
		packer.show ()
		vbox.pack_start (packer)
		frame = gtk.GtkFrame (_("Text Type"))
		frame.show ()
		packer.add (frame, pad_x=5, pad_y=5)
		hbox = gtk.GtkHBox ()
		hbox.show ()
		frame.add (hbox)

		self.local_button = gtk.GtkRadioButton (None, _("Local Text"))
		self.local_button.connect ("clicked", self.local_clicked)
		self.local_button.show ()
		self.remote_button = gtk.GtkRadioButton (self.local_button, _("Remote Text"))
		self.remote_button.connect ("clicked", self.remote_clicked)
		self.remote_button.show ()
		self.error_button = gtk.GtkRadioButton (self.local_button, _("Error Text"))
		self.error_button.connect ("clicked", self.error_clicked)
		self.error_button.show ()
		hbox.pack_start (self.local_button, padding=10)
		hbox.pack_start (self.remote_button, padding=10)
		hbox.pack_start (self.error_button, padding=10)

		# Set current values and load the local as default
		if opts.has_key ('local_color'):
			self.local_color = opts['local_color']
		if opts.has_key ('remote_color'):
			self.remote_color = opts['remote_color']
		if opts.has_key ('error_color'):
			self.error_color = opts['error_color']
		self.set_current_color (self.local_color)

	def set_current_color (self, color):

		# Assign the color twice so we set the current color,
		# as well as the memory slot
		self.color_select.set_color (color)
		self.color_select.set_color (color)

	def save_current_color (self):

		if self.local_button.get_active ():
			self.local_color = self.color_select.get_color ()
		elif self.remote_button.get_active ():
			self.remote_color = self.color_select.get_color ()
		elif self.error_button.get_active ():
			self.error_color = self.color_select.get_color ()

	def local_clicked (self, button):

		if self.local_button.get_active ():
			self.set_current_color (self.local_color)
		else:
			self.local_color = self.color_select.get_color ()

	def remote_clicked (self, button):

		if self.remote_button.get_active ():
			self.set_current_color (self.remote_color)
		else:
			self.remote_color = self.color_select.get_color ()

	def error_clicked (self, button):

		if self.error_button.get_active ():
			self.set_current_color (self.error_color)
		else:
			self.error_color = self.color_select.get_color ()

	def get_page (self):
		return self.page

	def get_options (self):

		return {
			'local_color' : self.local_color,
			'remote_color' : self.remote_color,
			'error_color' : self.error_color,
		}

class ExternalTab:

	def __init__ (self, opts):

		self.page = gtk.GtkFrame (_("External Helpers"))
		self.page.set_border_width (10)
		self.page.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		self.page.show ()

		vbox = gtk.GtkVBox ()
		vbox.show ()
		self.page.add (vbox)
		packer = gtk.GtkPacker ()
		packer.show ()
		vbox.pack_start (packer, expand=GTK.FALSE, fill=GTK.FALSE)
		table = gtk.GtkTable (2, 2)
		table.set_row_spacings (7)
		table.show ()
		packer.add (table, options=GTK.FILL_X, pad_x=15, pad_y=15)

		label = gtk.GtkLabel (_("Launching Apps:"))
		label.show ()
		table.attach (label, 0, 1, 0, 1)
		self.launcher = gtk.GtkEntry ()
		if opts is not None and opts['launcher']:
			self.launcher.set_text (opts['launcher'])
		self.launcher.show ()
		table.attach (self.launcher, 1, 2, 0, 1)

		label = gtk.GtkLabel (_("Viewer:"))
		label.show ()
		table.attach (label, 0, 1, 1, 2)
		self.viewer = gtk.GtkEntry ()
		if opts is not None and opts['viewer']:
			self.viewer.set_text (opts['viewer'])
		self.viewer.show ()
		table.attach (self.viewer, 1, 2, 1, 2)

	def get_options (self):

		return {
			'launcher' : self.launcher.get_text (),
			'viewer'   : self.viewer.get_text (),
		}

	def get_page (self):
		return self.page
