#
# 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, gtk
import main

class ConnectWin:

	dialog = None
	notebook = None

	login_tab = None
	advanced_tab = None
	settings_tab = None

	def __init__ (self, callback, default_opts):

		self.callback = callback

		self.dialog = gtk.GtkDialog ()
		self.dialog.set_title ("ftpcube - Connect")
		self.dialog.set_policy (gtk.FALSE, gtk.FALSE, gtk.TRUE)
		self.dialog.set_position (gtk.WIN_POS_CENTER)
		self.dialog.show ()

		box = gtk.GtkHBox (spacing=75)
		box.show ()
		self.dialog.action_area.add (box, padding=95)

		button = gtk.GtkButton ("Ok")
		button.set_usize (50, 25)
		button.connect ("clicked", self.ok)
		box.pack_start (button, expand=gtk.FALSE)
		button.show ()

		button = gtk.GtkButton ("Cancel")
		button.set_usize (50, 25)
		button.connect ("clicked", self.cancel)
		box.pack_start (button, expand=gtk.FALSE)
		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.login_tab = LoginTab (opts=default_opts)
		label = gtk.GtkLabel ("Login Info")
		label.set_padding (2, 2)
		label.show ()
		self.notebook.append_page (self.login_tab.get_page (), label)

		self.advanced_tab = AdvancedTab (opts=default_opts)
		label = gtk.GtkLabel ("Advanced")
		label.set_padding (2, 2)
		label.show ()
		self.notebook.append_page (self.advanced_tab.get_page (), label)

		self.settings_tab = SettingsTab (opts=default_opts)
		label = gtk.GtkLabel ("Settings")
		label.set_padding (2, 2)
		label.show ()
		self.notebook.append_page (self.settings_tab.get_page (), label)

	def ok (self, button):

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

	def cancel (self, button):

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

	def get_options (self):

		options = { }
		options.update (self.login_tab.get_options ())
		options.update (self.advanced_tab.get_options ())
		options.update (self.settings_tab.get_options ())
		return options

class LoginTab:

	page = None

	host = None
	port = None
	username = None
	password = None
	remote_dir = None

	personal_button = None
	anon_button = None

	def __init__ (self, opts=None):

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

		table = gtk.GtkTable (6, 1)
		table.set_row_spacings (2)
		table.set_col_spacings (5)
		table.set_homogeneous (gtk.FALSE)
		table.show ()
		self.page.add (table)

		packer = gtk.GtkPacker ()
		label = gtk.GtkLabel ("Host")
		label.show ()
		packer.show ()
		packer.add (label, anchor=GTK.ANCHOR_W)
		table.attach (packer, 0, 1, 0, 1, xpadding=12, ypadding=1)

		packer = gtk.GtkPacker ()
		label = gtk.GtkLabel ("Port")
		label.show ()
		packer.show ()
		packer.add (label, anchor=GTK.ANCHOR_W)
		table.attach (packer, 1, 2, 0, 1, xpadding=10, ypadding=1)

		self.host = gtk.GtkEntry ()
		if opts is not None and opts['host']:
			self.host.set_text (opts['host'])
		self.host.show ()
		table.attach (self.host, 0, 1, 1, 2, xoptions=GTK.FILL, xpadding=4, ypadding=1)

		packer = gtk.GtkPacker ()
		self.port = gtk.GtkEntry ()
		self.port.set_usize (50, -1)
		self.port.set_text ("%s" %main.app['port'])
		if opts is not None and opts['port']:
			self.port.set_text ("%s" %opts['port'])
		self.port.show ()
		packer.show ()
		packer.add (self.port, anchor=GTK.ANCHOR_W)
		table.attach (packer, 1, 2, 1, 2, xpadding=4, ypadding=1)

		packer = gtk.GtkPacker ()
		label = gtk.GtkLabel ("Username")
		label.show ()
		packer.show ()
		packer.add (label, anchor=GTK.ANCHOR_W)
		table.attach (packer, 0, 1, 2, 3, xpadding=12, ypadding=1)

		packer = gtk.GtkPacker ()
		label = gtk.GtkLabel ("Password")
		label.show ()
		packer.show ()
		packer.add (label, anchor=GTK.ANCHOR_W)
		table.attach (packer, 1, 2, 2, 3, xpadding=12, ypadding=1)

		self.username = gtk.GtkEntry ()
		if opts is not None and opts['username']:
			self.username.set_text (opts['username'])
		self.username.connect ("key_press_event", self.entry_update)
		self.username.show ()
		table.attach (self.username, 0, 1, 3, 4, xpadding=4, ypadding=1)

		self.password = gtk.GtkEntry ()
		self.password.set_visibility (gtk.FALSE)
		if opts is not None and opts['password']:
			self.password.set_text (opts['password'])
		self.password.connect ("key_press_event", self.entry_update)
		self.password.show ()
		table.attach (self.password, 1, 2, 3, 4, xpadding=4,  ypadding=1)

		packer = gtk.GtkPacker ()
		label = gtk.GtkLabel ("Remote Directory")
		label.show ()
		packer.show ()
		packer.add (label, anchor=GTK.ANCHOR_W)
		table.attach (packer, 0, 2, 4, 5, xpadding=12, ypadding=1)

		self.remote_dir = gtk.GtkEntry ()
		if opts is not None and opts['remotedir']:
			self.remote_dir.set_text (opts['remotedir'])
		self.remote_dir.show ()
		table.attach (self.remote_dir, 0, 2, 5, 6, xpadding=4, ypadding=1)

		box = gtk.GtkHBox ()
		box.show ()
		self.personal_button = gtk.GtkRadioButton (None, "Personal Login")
		self.personal_button.connect ("clicked", self.personal_clicked)
		self.personal_button.show ()
		self.anon_button = gtk.GtkRadioButton (self.personal_button, "Anonymous Login")
		self.anon_button.connect ("clicked", self.anon_clicked)
		self.anon_button.show ()
		self.anon_button.set_active (gtk.TRUE)
		box.pack_start (self.personal_button)
		box.pack_start (self.anon_button)
		table.attach (box, 0, 2, 6, 7, xpadding=4, ypadding=1)

	def entry_update (self, win, event):
		self.personal_button.set_active (gtk.TRUE)

	def get_page (self):
		return self.page

	def anon_clicked (self, button):

		self.username.set_text ("%s" %main.app['username'])
		self.password.set_text ("%s" %main.app['password'])

	def personal_clicked (self, button):

		self.username.set_text ('')
		self.password.set_text ('')

	def get_options (self):

		return {
			'host' : self.host.get_text (),
			'port' : int (self.port.get_text ()),
			'username' : self.username.get_text (),
			'password' : self.password.get_text (),
			'remotedir' : self.remote_dir.get_text ()
		}

class AdvancedTab:

	page = None

	localdir = None

	unlimited_button = None
	login_button = None
	limited_button = None
	limited_box = None

	def __init__ (self, opts=None):

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

		outterpacker = gtk.GtkPacker ()
		outterpacker.show ()
		self.page.add (outterpacker)

		frame = gtk.GtkFrame ()
		frame.set_border_width (10)
		frame.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		frame.set_usize (350, 85)
		frame.show ()
		outterpacker.add (frame)

		packer = gtk.GtkPacker ()
		packer.show ()
		frame.add (packer)
		label = gtk.GtkLabel ("Local Directory")
		label.show ()
		packer.add (label, side=GTK.SIDE_TOP, anchor=GTK.ANCHOR_W, pad_x=75, pad_y=12)
		box = gtk.GtkHBox ()
		box.show ()
		packer.add (box)
		self.localdir = gtk.GtkEntry ()
		if opts is not None and opts['localdir']:
			self.localdir.set_text (opts['localdir'])
		self.localdir.set_usize (200, -1)
		self.localdir.show ()
		box.pack_start (self.localdir, expand=GTK.EXPAND)
		button = gtk.GtkButton ("...")
		button.connect ("clicked", self.browse)
		button.set_usize (25, 25)
		button.show ()
		box.pack_start (button, expand=GTK.EXPAND, padding=25)

		frame = gtk.GtkFrame ()
		frame.set_border_width (10)
		frame.set_usize (350, 85)
		frame.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		frame.show ()
		outterpacker.add (frame)

		packer = gtk.GtkPacker ()
		packer.show ()
		frame.add (packer)
		label = gtk.GtkLabel ("Number of logins allowed:")
		label.show ()
		packer.add (label, side=GTK.SIDE_TOP, anchor=GTK.ANCHOR_NW, pad_x=55, pad_y=10)
		box = gtk.GtkHBox ()
		box.show ()
		self.unlimited_button = gtk.GtkRadioButton (None, "Unlimited")
		self.unlimited_button.show ()
		box.pack_start (self.unlimited_button, padding=4)
		self.unlimited_button.set_active (gtk.TRUE)
		self.login_button = gtk.GtkRadioButton (self.unlimited_button, "Login only once")
		self.login_button.show ()
		box.pack_start (self.login_button, padding=4)
		self.limited_button = gtk.GtkRadioButton (self.unlimited_button, "Limited")
		self.limited_button.show ()
		box.pack_start (self.limited_button, padding=4)
		self.limited_box = gtk.GtkEntry ()
		if opts is not None and opts['limit']:
			limit = opts['limit']
			if limit == 0:
				self.unlimited_button.set_active (gtk.TRUE)
			elif limit == 1:
				self.login.button.set_active (gtk.TRUE)
			else:
				self.unlimited_button.set_active (gtk.TRUE)
				self.limited_box.set_text (limit)
		self.limited_box.set_usize (25, 25)
		self.limited_box.show ()
		box.pack_start (self.limited_box, expand=GTK.EXPAND, padding=4)
		packer.add (box, anchor=GTK.ANCHOR_W, pad_x=15)

	def get_page (self):
		return self.page
 
	def browse (self, button):

		file_win = gtk.GtkFileSelection ("Browse")
		file_win.show ()

		# Create the handlers for browse events
		def win_close (button, win=file_win):
			win.hide ()
			win.destroy ()
		def browse_selected (button, fs=file_win, self=self):
			self.localdir.set_text (fs.get_filename ())
			fs.hide ()
			fs.destroy ()
		file_win.ok_button.connect("clicked", browse_selected)
		file_win.cancel_button.connect("clicked", win_close)

	def get_options (self):

		limit = None
		if self.login_button.get_active ():
			limit = 1
		elif self.limited_button.get_active ():
			text = self.limited_box.get_text ()
			if len (text) > 0:
				limit = int (text)

		return {
			'limit' : limit,
			'localdir' : self.localdir.get_text ()
		}

class SettingsTab:

	page = None

	retries_box = None
	idle_box = None
	timeout_box = None
	delay_box = None
	proxy_check = None

	def __init__ (self, opts=None):

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

		outterpacker = gtk.GtkPacker ()
		outterpacker.show ()
		self.page.add (outterpacker)

		frame = gtk.GtkFrame ()
		frame.set_border_width (10)
		frame.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		frame.set_usize (350, 130)
		frame.show ()
		outterpacker.add (frame)
 
		table = gtk.GtkTable (2, 4)
		table.set_col_spacing (0, 15)
		table.show ()
		frame.add (table)
		label = gtk.GtkLabel ("Connection Retries")
		label.show ()
		table.attach (label, 0, 1, 0, 1)
		label = gtk.GtkLabel ("Idle Timeout (sec)")
		label.show ()
		table.attach (label, 1, 2, 0, 1)
		self.retries_box = gtk.GtkEntry ()
		self.retries_box.set_usize (100, -1)
		if opts is not None and opts['retries']:
			self.retries_box.set_text ("%s" %opts['retries'])
		self.retries_box.show ()
		table.attach (self.retries_box, 0, 1, 1, 2, xoptions=GTK.EXPAND)
		self.idle_box = gtk.GtkEntry ()
		self.idle_box.set_usize (100, -1)
		if opts is not None and opts['main_idle']:
			self.idle_box.set_text ("%s" %opts['main_idle'])
		self.idle_box.show ()
		table.attach (self.idle_box, 1, 2, 1, 2, xoptions=GTK.EXPAND)
		label = gtk.GtkLabel ("Connect timeout (sec)")
		label.show ()
		table.attach (label, 0, 1, 2, 3)
		label = gtk.GtkLabel ("Login retry delay (sec)")
		label.show ()
		table.attach (label, 1, 2, 2, 3)
		self.timeout_box = gtk.GtkEntry ()
		self.timeout_box.set_usize (100, -1)
		if opts is not None and opts['timeout']:
			self.timeout_box.set_text ("%s" %opts['timeout'])
		self.timeout_box.show ()
		table.attach (self.timeout_box, 0, 1, 3, 4, xoptions=GTK.EXPAND)
		self.delay_box = gtk.GtkEntry ()
		self.delay_box.set_usize (100, -1)
		if opts is not None and opts['delay']:
			self.delay_box.set_text ("%s" %opts['delay'])
		self.delay_box.show ()
		table.attach (self.delay_box, 1, 2, 3, 4, xoptions=GTK.EXPAND)

		frame = gtk.GtkFrame ()
		frame.set_border_width (10)
		frame.set_shadow_type (gtk.SHADOW_ETCHED_OUT)
		frame.set_usize (350, 65)
		frame.show ()
		outterpacker.add (frame)

		box = gtk.GtkHBox ()
		box.show ()
		frame.add (box)
		self.proxy_check = gtk.GtkCheckButton ("Use proxy server")
		if opts is not None and opts['proxy']:
			self.proxy_check.set_active (gtk.TRUE)
		self.proxy_check.show ()
		box.pack_start (self.proxy_check, padding=100)

	def get_page (self):
		return self.page

	def get_options (self):

		return {
			'retries' : int (self.retries_box.get_text ()),
			'main_idle' : int (self.idle_box.get_text ()),
			'timeout' : int (self.timeout_box.get_text ()),
			'delay' : int (self.delay_box.get_text ()),
			'proxy' : self.proxy_check.get_active ()
		}

class QuickConnectWin:

	dialog = None
	entry = None

	def __init__ (self, callback, opts):

		self.callback = callback
		self.opts = opts

		self.dialog = gtk.GtkDialog ()
		self.dialog.set_title ("ftpcube - Quick Connect")
		self.dialog.set_policy (gtk.FALSE, gtk.FALSE, gtk.TRUE)
		self.dialog.set_position (gtk.WIN_POS_CENTER)
		self.dialog.show ()

		box = gtk.GtkHBox (spacing=50)
		box.show ()
		self.dialog.action_area.add (box, padding=50)

		button = gtk.GtkButton ("Ok")
		button.set_usize (50, 25)
		button.connect ("clicked", self.ok)
		box.pack_start (button, expand=gtk.FALSE)
		button.show ()

		button = gtk.GtkButton ("Cancel")
		button.set_usize (50, 25)
		button.connect ("clicked", self.cancel)
		box.pack_start (button, expand=gtk.FALSE)
		button.show ()

		packer = gtk.GtkPacker ()
		packer.show ()
		self.dialog.vbox.add (packer, padding=15)

		label = gtk.GtkLabel ("Hostname:")
		label.show ()
		packer.add (label, anchor=GTK.ANCHOR_NW, i_pad_x=45)
		self.entry = gtk.GtkEntry ()
		self.entry.set_usize (225, -1)
		self.entry.show ()
		packer.add (self.entry, options=GTK.EXPAND, i_pad_y=10)

	def ok (self, button):

		text = self.entry.get_text ()

		if text == '':
			return
		else:
			self.dialog.hide ()
			self.dialog.destroy ()
			self.callback (self)

	def cancel (self, button):

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

	def get_options (self):

		opts = self.opts
		opts['host'] = self.entry.get_text ()

		# Perform all conversions on the main.app defaults
		# to integers that require conversion
		if main.app['port']:
			opts['port'] = int (main.app['port'])
		if main.app['retries']:
			opts['retries'] = int (main.app['retries'])
		if main.app['main_idle']:
			opts['main_idle'] = int (main.app['main_idle'])
		if main.app['timeout']:
			opts['timeout'] = int (main.app['timeout'])
		if main.app['delay']:
			opts['delay'] = int (main.app['delay'])

		return opts
