using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Web.Services;
using System.Threading;
using System.IO;
using imagemanager.localhost;

namespace imagemanager
{
	public class MainForm : System.Windows.Forms.Form
	{
		private System.Windows.Forms.StatusBar statusBar;
		private System.Windows.Forms.ColumnHeader recordColumnHeader;
		private System.Windows.Forms.ColumnHeader resourceColumnHeader;
		private System.Windows.Forms.ColumnHeader statusColumnHeader;
		private System.Windows.Forms.ColumnHeader actionColumnHeader;
		private System.Windows.Forms.ColumnHeader localResourceColumnHeader;
		private System.Windows.Forms.ListView resourceListView;
		private System.ComponentModel.IContainer components;
		private System.Windows.Forms.MenuItem FileMenuItem;
		private System.Windows.Forms.MenuItem FileConnectMenuItem;
		private System.Windows.Forms.MenuItem FileDisconnectMenuItem;
		private System.Windows.Forms.MenuItem FileSeparator1MenuItem;
		private System.Windows.Forms.MenuItem FileExitMenuItem;
		private System.Windows.Forms.MainMenu mainMenu;
		private System.Windows.Forms.MenuItem CollectionMenuItem;
		private System.Windows.Forms.MenuItem CollectionSelectMenuItem;
		private System.Windows.Forms.MenuItem CollectionSeparator1MenuItem;
		private System.Windows.Forms.MenuItem CollectionAssignLocalResourcesMenuItem;
		private System.Windows.Forms.ToolBar toolBar;
		private System.Windows.Forms.ToolBarButton SelectAllToolBarButton;
		private System.Windows.Forms.ToolBarButton SelectProblemsToolBarButton;
		private System.Windows.Forms.ImageList ToolBarImageList;
		private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog;
		
		private string token = null;
		private Thread keepaliveThread = null;
		private ImageManager manager = new ImageManager();
		private CollectionInfo collectioninfo = null;
		private int sortedcolumn = -1;
		private System.Windows.Forms.ToolBarButton ActionUploadToolBarButton;
		private System.Windows.Forms.ToolBarButton ActionNoneToolBarButton;
		private bool connected = false;

		private readonly string ACTION_NONE_TEXT = "None";
		private readonly System.Drawing.Color ACTION_NONE_COLOR = System.Drawing.Color.Black;
		private readonly string ACTION_UPLOAD_TEXT = "Upload";
		private readonly System.Drawing.Color ACTION_UPLOAD_COLOR = System.Drawing.Color.DarkGreen;
		private readonly string STATUS_OK_TEXT = "Ok";
		private readonly System.Drawing.Color STATUS_OK_COLOR = System.Drawing.Color.Black;
		private readonly string STATUS_MISSING_TEXT = "Missing Files";
		private System.Windows.Forms.ToolBarButton HideValidToolBarButton;
		private System.Windows.Forms.ToolBarButton Separator1ToolBarButton;
		private System.Windows.Forms.ToolBarButton Separator2ToolBarButton;
		private System.Windows.Forms.ToolBarButton Separator3ToolBarButton;
		private System.Windows.Forms.ToolBarButton StartToolBarButton;
		private readonly System.Drawing.Color STATUS_MISSING_COLOR = System.Drawing.Color.Red;

		public MainForm()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// Add any constructor code after InitializeComponent call
			//
			UpdateControlStatus(true);
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(MainForm));
			this.statusBar = new System.Windows.Forms.StatusBar();
			this.resourceListView = new System.Windows.Forms.ListView();
			this.recordColumnHeader = new System.Windows.Forms.ColumnHeader();
			this.resourceColumnHeader = new System.Windows.Forms.ColumnHeader();
			this.statusColumnHeader = new System.Windows.Forms.ColumnHeader();
			this.actionColumnHeader = new System.Windows.Forms.ColumnHeader();
			this.localResourceColumnHeader = new System.Windows.Forms.ColumnHeader();
			this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
			this.mainMenu = new System.Windows.Forms.MainMenu();
			this.FileMenuItem = new System.Windows.Forms.MenuItem();
			this.FileConnectMenuItem = new System.Windows.Forms.MenuItem();
			this.FileDisconnectMenuItem = new System.Windows.Forms.MenuItem();
			this.FileSeparator1MenuItem = new System.Windows.Forms.MenuItem();
			this.FileExitMenuItem = new System.Windows.Forms.MenuItem();
			this.CollectionMenuItem = new System.Windows.Forms.MenuItem();
			this.CollectionSelectMenuItem = new System.Windows.Forms.MenuItem();
			this.CollectionSeparator1MenuItem = new System.Windows.Forms.MenuItem();
			this.CollectionAssignLocalResourcesMenuItem = new System.Windows.Forms.MenuItem();
			this.toolBar = new System.Windows.Forms.ToolBar();
			this.SelectAllToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.SelectProblemsToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.ToolBarImageList = new System.Windows.Forms.ImageList(this.components);
			this.ActionUploadToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.ActionNoneToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.HideValidToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.Separator1ToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.Separator2ToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.Separator3ToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.StartToolBarButton = new System.Windows.Forms.ToolBarButton();
			this.SuspendLayout();
			// 
			// statusBar
			// 
			this.statusBar.Location = new System.Drawing.Point(0, 349);
			this.statusBar.Name = "statusBar";
			this.statusBar.Size = new System.Drawing.Size(612, 22);
			this.statusBar.TabIndex = 0;
			this.statusBar.Text = "Not connected";
			// 
			// resourceListView
			// 
			this.resourceListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																							   this.recordColumnHeader,
																							   this.resourceColumnHeader,
																							   this.statusColumnHeader,
																							   this.actionColumnHeader,
																							   this.localResourceColumnHeader});
			this.resourceListView.Dock = System.Windows.Forms.DockStyle.Fill;
			this.resourceListView.FullRowSelect = true;
			this.resourceListView.GridLines = true;
			this.resourceListView.HideSelection = false;
			this.resourceListView.LabelWrap = false;
			this.resourceListView.Location = new System.Drawing.Point(0, 42);
			this.resourceListView.Name = "resourceListView";
			this.resourceListView.Size = new System.Drawing.Size(612, 307);
			this.resourceListView.TabIndex = 1;
			this.resourceListView.View = System.Windows.Forms.View.Details;
			this.resourceListView.DoubleClick += new System.EventHandler(this.resourceListView_DoubleClick);
			this.resourceListView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.resourceListView_ColumnClick);
			this.resourceListView.SelectedIndexChanged += new System.EventHandler(this.resourceListView_SelectedIndexChanged);
			// 
			// recordColumnHeader
			// 
			this.recordColumnHeader.Text = "Record";
			this.recordColumnHeader.Width = 67;
			// 
			// resourceColumnHeader
			// 
			this.resourceColumnHeader.Text = "Resource";
			this.resourceColumnHeader.Width = 104;
			// 
			// statusColumnHeader
			// 
			this.statusColumnHeader.Text = "Status";
			this.statusColumnHeader.Width = 108;
			// 
			// actionColumnHeader
			// 
			this.actionColumnHeader.Text = "Action";
			this.actionColumnHeader.Width = 112;
			// 
			// localResourceColumnHeader
			// 
			this.localResourceColumnHeader.Text = "Local Resource";
			this.localResourceColumnHeader.Width = 149;
			// 
			// folderBrowserDialog
			// 
			this.folderBrowserDialog.Description = "Select the folder that contains files you want to use as image resources";
			this.folderBrowserDialog.ShowNewFolderButton = false;
			// 
			// mainMenu
			// 
			this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					 this.FileMenuItem,
																					 this.CollectionMenuItem});
			// 
			// FileMenuItem
			// 
			this.FileMenuItem.Index = 0;
			this.FileMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																						 this.FileConnectMenuItem,
																						 this.FileDisconnectMenuItem,
																						 this.FileSeparator1MenuItem,
																						 this.FileExitMenuItem});
			this.FileMenuItem.Text = "File";
			// 
			// FileConnectMenuItem
			// 
			this.FileConnectMenuItem.Index = 0;
			this.FileConnectMenuItem.Text = "Connect...";
			this.FileConnectMenuItem.Click += new System.EventHandler(this.FileConnectMenuItem_Click);
			// 
			// FileDisconnectMenuItem
			// 
			this.FileDisconnectMenuItem.Index = 1;
			this.FileDisconnectMenuItem.Text = "Disconnect";
			this.FileDisconnectMenuItem.Click += new System.EventHandler(this.FileDisconnectMenuItem_Click);
			// 
			// FileSeparator1MenuItem
			// 
			this.FileSeparator1MenuItem.Index = 2;
			this.FileSeparator1MenuItem.Text = "-";
			// 
			// FileExitMenuItem
			// 
			this.FileExitMenuItem.Index = 3;
			this.FileExitMenuItem.Text = "Exit";
			this.FileExitMenuItem.Click += new System.EventHandler(this.FileExitMenuItem_Click);
			// 
			// CollectionMenuItem
			// 
			this.CollectionMenuItem.Index = 1;
			this.CollectionMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																							   this.CollectionSelectMenuItem,
																							   this.CollectionSeparator1MenuItem,
																							   this.CollectionAssignLocalResourcesMenuItem});
			this.CollectionMenuItem.Text = "Collection";
			// 
			// CollectionSelectMenuItem
			// 
			this.CollectionSelectMenuItem.Index = 0;
			this.CollectionSelectMenuItem.Text = "Select...";
			this.CollectionSelectMenuItem.Click += new System.EventHandler(this.CollectionSelectMenuItem_Click);
			// 
			// CollectionSeparator1MenuItem
			// 
			this.CollectionSeparator1MenuItem.Index = 1;
			this.CollectionSeparator1MenuItem.Text = "-";
			// 
			// CollectionAssignLocalResourcesMenuItem
			// 
			this.CollectionAssignLocalResourcesMenuItem.Index = 2;
			this.CollectionAssignLocalResourcesMenuItem.Text = "Assign Local Resources...";
			this.CollectionAssignLocalResourcesMenuItem.Click += new System.EventHandler(this.CollectionAssignLocalResourcesMenuItem_Click);
			// 
			// toolBar
			// 
			this.toolBar.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
																					   this.SelectAllToolBarButton,
																					   this.SelectProblemsToolBarButton,
																					   this.Separator1ToolBarButton,
																					   this.HideValidToolBarButton,
																					   this.Separator2ToolBarButton,
																					   this.ActionUploadToolBarButton,
																					   this.ActionNoneToolBarButton,
																					   this.Separator3ToolBarButton,
																					   this.StartToolBarButton});
			this.toolBar.DropDownArrows = true;
			this.toolBar.ImageList = this.ToolBarImageList;
			this.toolBar.Location = new System.Drawing.Point(0, 0);
			this.toolBar.Name = "toolBar";
			this.toolBar.ShowToolTips = true;
			this.toolBar.Size = new System.Drawing.Size(612, 42);
			this.toolBar.TabIndex = 2;
			this.toolBar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
			// 
			// SelectAllToolBarButton
			// 
			this.SelectAllToolBarButton.ImageIndex = 0;
			this.SelectAllToolBarButton.Text = "Select All";
			// 
			// SelectProblemsToolBarButton
			// 
			this.SelectProblemsToolBarButton.ImageIndex = 1;
			this.SelectProblemsToolBarButton.Text = "Select Problems";
			// 
			// ToolBarImageList
			// 
			this.ToolBarImageList.ImageSize = new System.Drawing.Size(16, 16);
			this.ToolBarImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ToolBarImageList.ImageStream")));
			this.ToolBarImageList.TransparentColor = System.Drawing.Color.Lime;
			// 
			// ActionUploadToolBarButton
			// 
			this.ActionUploadToolBarButton.ImageIndex = 2;
			this.ActionUploadToolBarButton.Text = "Action: Upload";
			// 
			// ActionNoneToolBarButton
			// 
			this.ActionNoneToolBarButton.ImageIndex = 3;
			this.ActionNoneToolBarButton.Text = "Action: None";
			// 
			// HideValidToolBarButton
			// 
			this.HideValidToolBarButton.ImageIndex = 4;
			this.HideValidToolBarButton.Text = "Hide Valid";
			// 
			// Separator1ToolBarButton
			// 
			this.Separator1ToolBarButton.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
			// 
			// Separator2ToolBarButton
			// 
			this.Separator2ToolBarButton.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
			// 
			// Separator3ToolBarButton
			// 
			this.Separator3ToolBarButton.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
			// 
			// StartToolBarButton
			// 
			this.StartToolBarButton.ImageIndex = 5;
			this.StartToolBarButton.Text = "Start";
			// 
			// MainForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(612, 371);
			this.Controls.Add(this.resourceListView);
			this.Controls.Add(this.statusBar);
			this.Controls.Add(this.toolBar);
			this.Menu = this.mainMenu;
			this.MinimumSize = new System.Drawing.Size(620, 400);
			this.Name = "MainForm";
			this.Text = "MDID Image Manager";
			this.Closing += new System.ComponentModel.CancelEventHandler(this.MainForm_Closing);
			this.Activated += new System.EventHandler(this.MainForm_Activated);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			MainForm form = new MainForm();
			Application.Run(form);
		}

		private void KeepAlive()
		{
			while (true)
			{			
				try
				{
					Thread.Sleep(TimeSpan.FromMinutes(5));
					manager.KeepAlive(token);
				}
				catch (ThreadAbortException)
				{
					break;
				}
			}
		}

		private void resourceListView_DoubleClick(object sender, System.EventArgs e)
		{
			if (resourceListView.SelectedItems.Count > 0)
			{
				ListViewItem item = resourceListView.SelectedItems[0];
				PropertiesForm form = new PropertiesForm(
					item.SubItems[0].Text,
					item.SubItems[1].Text,
					item.SubItems[2].Text,
					item.SubItems[3].Text,
					item.SubItems[4].Text);
				if (form.ShowDialog(this) == DialogResult.OK)
				{
					string action = form.Action;
					item.SubItems[3].Text = action;
					if (action == ACTION_NONE_TEXT)
						item.SubItems[3].ForeColor = ACTION_NONE_COLOR;
					else if (action == ACTION_UPLOAD_TEXT)
						item.SubItems[3].ForeColor = ACTION_UPLOAD_COLOR;
					else
						throw new Exception("Unknown action code");
					item.SubItems[4].Text = form.LocalResource;
				}
			}
		}

		private void Disconnect()
		{
			UpdateControlStatus(false);
			ProgressForm form = new ProgressForm("Disconnecting",
				"Disconnecting from server. Please wait.", false, false);
			form.Show();
			Application.DoEvents();
			if (keepaliveThread != null)
				keepaliveThread.Abort();
			keepaliveThread = null;
			token = null;
			collectioninfo = null;
			connected = false;
			UpdateResourceListView();
			form.Finished();
			UpdateControlStatus(true);
			statusBar.Text = "Disconnected";
		}

		private void UpdateResourceListView()
		{
			resourceListView.Items.Clear();
			if (collectioninfo != null)
			{
				UpdateControlStatus(false);
				ProgressForm form = new ProgressForm("Retrieving data",
					"Retrieving collection data from server. Please wait.", false, false);
				form.Show();
				Application.DoEvents();				
				ImageInfo[] info = manager.GetCollectionData(token, collectioninfo.id);
				Application.DoEvents();	
				string[] files = manager.GetAvailableResources(token, collectioninfo.id);
				if (files == null)
					files = new string[0];
				Application.DoEvents();	
				if (info != null)
				{
					Array.Sort(files);
					ArrayList items = new ArrayList();
					foreach (ImageInfo i in info)
					{
						bool hasallfiles =
							(Array.BinarySearch(files, i.full, new CaseInsensitiveComparer()) >= 0) &&
							(Array.BinarySearch(files, i.medium, new CaseInsensitiveComparer()) >= 0) &&
							(Array.BinarySearch(files, i.thumb, new CaseInsensitiveComparer()) >= 0);
						string status = (hasallfiles ? STATUS_OK_TEXT : STATUS_MISSING_TEXT);
						System.Drawing.Color color = (hasallfiles ? STATUS_OK_COLOR : STATUS_MISSING_COLOR);
						ListViewItem item = new ListViewItem(
							new ListViewItem.ListViewSubItem[] {
								new ListViewItem.ListViewSubItem(null, i.id),
								new ListViewItem.ListViewSubItem(null, i.resource),
								new ListViewItem.ListViewSubItem(null, status, color, resourceListView.BackColor, null),
								new ListViewItem.ListViewSubItem(null, ACTION_NONE_TEXT, ACTION_NONE_COLOR, resourceListView.BackColor, null),
								new ListViewItem.ListViewSubItem(null, "")
							}, 0);
						item.UseItemStyleForSubItems = false;
						items.Add(item);						
					}
					resourceListView.BeginUpdate();
					resourceListView.Items.AddRange((ListViewItem[])items.ToArray(typeof(ListViewItem)));
					resourceListView.ListViewItemSorter = new ListViewItemComparer(0, SortOrder.Ascending);
					resourceListView.Sort();
					resourceListView.EndUpdate();
				}
				form.Finished();
				UpdateControlStatus(true);
			}
		}

		private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			Disconnect();
		}

		private void resourceListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
		{
			SortOrder order;
			if (sortedcolumn == e.Column)
			{
				order = SortOrder.Descending;
				sortedcolumn = -1;
			}
			else
			{
				order = SortOrder.Ascending;
				sortedcolumn = e.Column;
			}
			resourceListView.ListViewItemSorter = new ListViewItemComparer(e.Column, order);
			resourceListView.Sort();
		}

		private void FileExitMenuItem_Click(object sender, System.EventArgs e)
		{
			Close();
		}

		private void FileDisconnectMenuItem_Click(object sender, System.EventArgs e)
		{
			Disconnect();
		}

		private void Connect()
		{
			LoginForm form = new LoginForm();
			while (form.ShowDialog(this) == DialogResult.OK)
			{
				Disconnect();
				UpdateControlStatus(false);
				ProgressForm pform = new ProgressForm("Connecting",
					"Connecting to server. Please wait.", false, false);
				pform.Show();
				Application.DoEvents();
				string url = form.ServerUrl;
				if (!url.EndsWith("/"))
					url += "/";
				url += "WebServices/ImageManager.asmx";
				manager.Url = url;
				manager.Timeout = 15 * 60 * 1000; // 15 minute timeout
				try
				{
					token = manager.Login(form.User, form.Password);
					if (token != null)
					{
						keepaliveThread = new Thread(new ThreadStart(KeepAlive));
						keepaliveThread.Name = "KeepAlive";
						keepaliveThread.Start();
						statusBar.Text = "Connected";
						connected = true;
						break;
					}
					else
						MessageBox.Show("Invalid username or password");
				}
				catch (Exception ex)
				{
					Disconnect();
					MessageBox.Show(ex.Message);
				}
				finally
				{
					pform.Finished();
					UpdateControlStatus(true);
				}
			}
			if (connected)
				SelectCollection();
		}

		private void FileConnectMenuItem_Click(object sender, System.EventArgs e)
		{
			Connect();
		}

		private void SelectCollection()
		{
			CollectionSelectForm form = new CollectionSelectForm(manager, token);
			if (form.ShowDialog(this) == DialogResult.OK)
			{
				collectioninfo = form.GetCollectionInfo();
				UpdateResourceListView();
			}
		}
		
		private void CollectionSelectMenuItem_Click(object sender, System.EventArgs e)
		{
			SelectCollection();
		}

		private void toolBar_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
		{
			if (e.Button == this.SelectAllToolBarButton)
			{
				foreach (ListViewItem item in resourceListView.Items)
					item.Selected = true;
			}
			else if (e.Button == this.SelectProblemsToolBarButton)
			{
				foreach (ListViewItem item in resourceListView.Items)
					item.Selected = (item.SubItems[2].Text != STATUS_OK_TEXT);
			}
			else if (e.Button == this.ActionUploadToolBarButton)
			{
				foreach (ListViewItem item in resourceListView.Items)
					if (item.Selected)
					{
						item.SubItems[3].Text = ACTION_UPLOAD_TEXT;
						item.SubItems[3].ForeColor = ACTION_UPLOAD_COLOR;
					}
			}
			else if (e.Button == this.ActionNoneToolBarButton)
			{
				foreach (ListViewItem item in resourceListView.Items)
					if (item.Selected)
					{
						item.SubItems[3].Text = ACTION_NONE_TEXT;
						item.SubItems[3].ForeColor = ACTION_NONE_COLOR;
					}
			}
			else if (e.Button == this.HideValidToolBarButton)
			{
				for (int i = resourceListView.Items.Count - 1; i >= 0; i--)
					if (resourceListView.Items[i].SubItems[2].Text == STATUS_OK_TEXT)
						resourceListView.Items.RemoveAt(i);
			}
			else if (e.Button == this.StartToolBarButton)
			{
				PerformActions();
			}
		}

		private void UpdateControlStatus(bool enable)
		{
			resourceListView.Enabled = (collectioninfo != null) && enable;
			SelectAllToolBarButton.Enabled = (collectioninfo != null) && enable;
			SelectProblemsToolBarButton.Enabled = (collectioninfo != null) && enable;
			HideValidToolBarButton.Enabled = (collectioninfo != null) && enable;
			StartToolBarButton.Enabled = (collectioninfo != null) && enable;
			FileMenuItem.Enabled = enable;
			FileConnectMenuItem.Enabled = enable;
			FileDisconnectMenuItem.Enabled = connected && enable;
			FileExitMenuItem.Enabled = enable;
			CollectionMenuItem.Enabled = enable;
			CollectionSelectMenuItem.Enabled = connected && enable;
			UpdateSelectionBasedActionStatus(enable);
		}

		private void UpdateSelectionBasedActionStatus(bool enable)
		{
			bool selected = (collectioninfo != null) && (resourceListView.SelectedItems.Count > 0);
			CollectionAssignLocalResourcesMenuItem.Enabled = enable && selected;
			ActionUploadToolBarButton.Enabled = enable && selected; 
			ActionNoneToolBarButton.Enabled = enable && selected;
		}

		private void CollectionAssignLocalResourcesMenuItem_Click(object sender, System.EventArgs e)
		{
			if (folderBrowserDialog.ShowDialog(this) == DialogResult.OK)
			{
				Hashtable files = new Hashtable();
				foreach (string file in Directory.GetFiles(folderBrowserDialog.SelectedPath))
				{
					string f = Path.GetFileNameWithoutExtension(file).ToLower();
					if (!files.ContainsKey(f))
						files.Add(f, file);
				}
				foreach (ListViewItem item in resourceListView.Items)
					if (item.Selected)
					{
						string resource = Path.GetFileNameWithoutExtension(item.SubItems[1].Text).ToLower();
						if (files.ContainsKey(resource))
						{
							string localresource = item.SubItems[4].Text;
							if (localresource == null || localresource.Length == 0)
							{
								item.SubItems[4].Text = 
									Path.Combine(folderBrowserDialog.SelectedPath, (string)files[resource]);
								if (item.SubItems[2].Text != STATUS_OK_TEXT)
								{
									item.SubItems[3].Text = ACTION_UPLOAD_TEXT;
									item.SubItems[3].ForeColor = ACTION_UPLOAD_COLOR;
								}
							}
						}
					}
			}
		}

		private void resourceListView_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			UpdateSelectionBasedActionStatus(true);
		}

		private bool firstactivation = true;

		private void MainForm_Activated(object sender, System.EventArgs e)
		{
			if (firstactivation)
			{
				firstactivation = false;
				Connect();
			}
		}
		
		class ListViewItemComparer: 
			IComparer 
		{
			private int col;
			private SortOrder order;

			public ListViewItemComparer(int column, SortOrder o) 
			{
				col = column;
				order = o;
			}

			public int Compare(object x, object y) 
			{
				if (order == SortOrder.Descending)
					return -String.Compare(((ListViewItem)x).SubItems[col].Text, 
						((ListViewItem)y).SubItems[col].Text);
				else
					return String.Compare(((ListViewItem)x).SubItems[col].Text, 
						((ListViewItem)y).SubItems[col].Text);
			}
		}

		private void PerformActions()
		{
			ArrayList todo = new ArrayList();
			foreach (ListViewItem item in resourceListView.Items)
				if (item.SubItems[3].Text != ACTION_NONE_TEXT)
					todo.Add(item);
			if (todo.Count == 0)
				MessageBox.Show(this, "No actions to perform.", "Start", MessageBoxButtons.OK,
					MessageBoxIcon.Information);
			else
			{
				UpdateControlStatus(false);
				ProgressForm pform = new ProgressForm("Performing Actions",
					"", true, true);
				pform.Show();				
				int count = 0;
				foreach (ListViewItem item in todo)
				{
					string id = item.SubItems[0].Text;
					string resource = item.SubItems[1].Text;
					pform.Message = String.Format("Processing {0} ({1})", id, resource);

					Application.DoEvents();
					if (pform.CancelPressed)
						break;

					if (item.SubItems[3].Text == ACTION_UPLOAD_TEXT)
					{
						string localresource = item.SubItems[4].Text;
						if (localresource == null || localresource.Length == 0)
							continue;
						
						FileStream infile;
						Bitmap source;
						try
						{
							infile = File.OpenRead(localresource);
							source = new Bitmap(infile);
						}
						catch (Exception)
						{
							if (AskToContinue(String.Format("Error while reading " +
								"image file '{0}'.", localresource)) == DialogResult.Yes)
								continue;
							else
								break;
						}
													
						byte[] data = ProcessImage(source, collectioninfo.full);
						if (data == null || !manager.SetResourceData(token, id, ImageSize.Full, data))
							if (AskToContinue(String.Format("Error while saving full version for " +
								"image {0} (Remote resource '{1}', local resource '{2}').", 
								id,	resource, localresource)) != DialogResult.Yes)
								break;
						Application.DoEvents();
						if (pform.CancelPressed)
							break;

						data = ProcessImage(source, collectioninfo.medium);
						if (data == null || !manager.SetResourceData(token, id, ImageSize.Medium, data))
							if (AskToContinue(String.Format("Error while saving medium version for " +
								"image {0} (Remote resource '{1}', local resource '{2}').", 
								id,	resource, localresource)) != DialogResult.Yes)
								break;
						Application.DoEvents();
						if (pform.CancelPressed)
							break;

						data = ProcessImage(source, collectioninfo.thumbnail);
						if (data == null || !manager.SetResourceData(token, id, ImageSize.Thumbnail, data))
							if (AskToContinue(String.Format("Error while saving thumbnail version for " +
								"image {0} (Remote resource '{1}', local resource '{2}').", 
								id,	resource, localresource)) != DialogResult.Yes)
								break;
					}
					count++;
					pform.Progress = 100 * count / todo.Count;
				}
				pform.Finished();
				UpdateControlStatus(true);
				UpdateResourceListView();
			}
		}

		private DialogResult AskToContinue(string msg)
		{
			return MessageBox.Show(msg + " Do you want to continue?", "Processing", 
				MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
		}

		private byte[] ProcessImage(Bitmap image, ImageSettings target)
		{
			try
			{
				int width = image.Width;
				int height = image.Height;
				int newwidth = width;
				int newheight = height;
				if (width > target.width || height > target.height)
				{
					float xscale = (width > target.width ? (float)target.width / width : 1);
					float yscale = (height > target.height ? (float)target.height / height : 1);
					newwidth = (xscale < yscale ? target.width : (int)(width * yscale));
					newheight = (xscale < yscale ? (int)(height * xscale) : target.height);
				}
				Bitmap newimage = new Bitmap(target.fixedsize ? target.width : newwidth, 
					target.fixedsize ? target.height : newheight, PixelFormat.Format24bppRgb);
				Graphics g = Graphics.FromImage(newimage);
				if (target.fixedsize)
				{
					g.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(255, System.Drawing.Color.FromArgb(target.backgroundcolor))), 0, 0, target.width, target.height);
					g.DrawImage(image, (target.width - newwidth) / 2, (target.height - newheight) / 2,
						newwidth, newheight);
				}
				else
				{
					g.DrawImage(image, 0, 0, newwidth, newheight);
				}
				EncoderParameters ep = new EncoderParameters();
				ep.Param[0] = new EncoderParameter(Encoder.Quality, new long[] { target.quality });
				ImageCodecInfo jpegencoder = null;
				foreach (ImageCodecInfo ici in ImageCodecInfo.GetImageEncoders())
					if (ici.FormatDescription == "JPEG")
					{
						jpegencoder = ici;
						break;
					}
				if (jpegencoder == null)
					throw new Exception("No JPEG encoder found");
				MemoryStream outstream = new MemoryStream();
				newimage.Save(outstream, jpegencoder, ep);
				return outstream.ToArray();
			}
			catch (Exception)
			{
				return null;
			}
		}
	}
}
