using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Text.RegularExpressions;
using Orciid.Core;
using Orciid.UserControls;

namespace Orciid
{
	public struct ResultPageOptions
	{
		public string pagetitle;
		public string returnurl;
		public string returntitle;
		public ImageIdentifier[] images;

		public ResultPageOptions(string t, string u, string rt, ImageIdentifier[] i)
		{
			pagetitle = t;
			returnurl = u;
			returntitle = rt;
			images = i;
		}
	}

	public class result : PageTemplate.OrciidPage 
	{
		protected System.Web.UI.WebControls.Repeater R;
		protected System.Web.UI.WebControls.Button FirstPageButton;
		protected System.Web.UI.WebControls.Button PrevPageButton;
		protected System.Web.UI.WebControls.Label CurrentPageLabel;
		protected System.Web.UI.WebControls.Label TotalPagesLabel;
		protected System.Web.UI.WebControls.Label NumRecordsLabel;
		protected System.Web.UI.WebControls.Button NextPageButton;
		protected System.Web.UI.WebControls.Button LastPageButton;
		protected System.Web.UI.WebControls.Button FirstPageButton2;
		protected System.Web.UI.WebControls.Button PrevPageButton2;
		protected System.Web.UI.WebControls.Label CurrentPageLabel2;
		protected System.Web.UI.WebControls.Label TotalPagesLabel2;
		protected System.Web.UI.WebControls.Label NumRecordsLabel2;
		protected System.Web.UI.WebControls.Button NextPageButton2;
		protected System.Web.UI.WebControls.Button LastPageButton2;
		protected System.Web.UI.WebControls.DropDownList RecordsPerPageList;
		protected System.Web.UI.WebControls.DropDownList SortByList;
	
		private ImageIdentifier[] images;
//		private PersonalImageInfo[] personalimageinfo;
		private ArrayList selectedImages;
		private ImageIdentifier[] favorites = null;
		private bool hasfavorites;
		protected System.Web.UI.WebControls.DropDownList ViewModeList;
		protected System.Web.UI.WebControls.Panel SlideIconExplanation;
		protected System.Web.UI.HtmlControls.HtmlGenericControl Title;
		protected System.Web.UI.HtmlControls.HtmlGenericControl PageTitle;
		protected System.Web.UI.WebControls.LinkButton BackLinkButton;
		protected System.Web.UI.HtmlControls.HtmlGenericControl ShareBreak;
		protected System.Web.UI.HtmlControls.HtmlGenericControl SortBySpan;
		private Orciid.Core.Image[] imageobjects = null;
		protected System.Web.UI.WebControls.TextBox SaveSearchTextBox;
		protected System.Web.UI.WebControls.Button SaveSearchButton;
		protected System.Web.UI.HtmlControls.HtmlGenericControl SaveSearchDiv;
		protected System.Web.UI.WebControls.Label Label1;
		private string[] annotations = null;
		private bool[] hasRelatedImages = null;
		private int[] inSlideshowCount = null;

		private int currentpage;
		private int totalpages;
		private int numrecords;
		private string inslideshowtitle;
		private ImageIdentifier[] inslideshow;
		private ImageIdentifier editimagenotes;
		private SearchField[] sort;
		protected System.Web.UI.WebControls.LinkButton SelectAllOnPageLinkButton;
		protected System.Web.UI.HtmlControls.HtmlGenericControl ShowLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl RecordsPerPageLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl SortedByLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl ShowInfoLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl InformationLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl PageLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl OfPagesLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl RecordsFoundLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl PageLabel2;
		protected System.Web.UI.HtmlControls.HtmlGenericControl OfPagesLabel2;
		protected System.Web.UI.HtmlControls.HtmlGenericControl RecordsFoundLabel2;
		protected System.Web.UI.HtmlControls.HtmlGenericControl ImageAlreadyInSlideshowLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl SaveSearchLabel;
		protected System.Web.UI.WebControls.PlaceHolder ScrollToImageNotesPlaceHolder;
		protected System.Web.UI.WebControls.TextBox FilterTextBox;
		protected System.Web.UI.WebControls.Button FilterButton;
		private Hashtable ids = new Hashtable();

		// used to count displayed records so a break can be inserted at regular
		// intervals in compact view
		private int RecordDisplayCounter;

		private void Page_Load(object sender, System.EventArgs e)
		{
			try
			{
				images = ((ResultPageOptions)Session["LastSearchResult"]).images;
			}
			catch (Exception)
			{
				images = null;
			}
			if (images == null || images.Length == 0)
				Response.Redirect("addimages.aspx"); 

			ResultPageOptions rpo = (ResultPageOptions)Session["LastSearchResult"];
			Title.InnerText = rpo.pagetitle;
			PageTitle.InnerText = rpo.pagetitle;
			if (rpo.returnurl != null)
			{
				BackLinkButton.Visible = true;
				BackLinkButton.Text = rpo.returntitle;
			}
			else
				BackLinkButton.Visible = false;

			SelectAllOnPageLinkButton.Visible = ((PageTemplate.OrciidPage)Page).UserCanBuildSlideshows;

			selectedImages = Session["SelectedImages"] as ArrayList;
			if (selectedImages == null)
				selectedImages = new ArrayList();

			if (!IsPostBack)
			{
				ViewModeList.Items.Clear();
				ViewModeList.Items.Add(new ListItem(GetLocalString(this, "NoLabel", "no"), "none"));
				ViewModeList.Items.Add(new ListItem(GetLocalString(this, "LessLabel", "less"), "short"));
				ViewModeList.Items.Add(new ListItem(GetLocalString(this, "MoreLabel", "more"), "long"));
				ViewModeList.SelectedValue = "short";

				Orciid.Core.User user = Orciid.Core.User.CurrentUser();
				Properties props = (user is AnonymousUser ? null : Properties.GetProperties(user));
				string preferredsortbyfield = (props == null ? null : props.Get("sortbyfield", null));
				string preferredrecordsperpage = (props == null ? null : props.Get("recordsperpage", null));
				string preferredviewmode = (props == null ? null : props.Get("resultviewmode", null));

				if (preferredviewmode != null)
				{
					ListItem viewmodeitem = ViewModeList.Items.FindByValue(preferredviewmode);
					if (viewmodeitem != null)
						ViewModeList.SelectedValue = preferredviewmode;
				}

				if (preferredrecordsperpage != null)
					RecordsPerPageList.SelectedValue = preferredrecordsperpage;

				try
				{
					currentpage = Int32.Parse(Request.QueryString["page"]);
				}
				catch
				{
					currentpage = 1;
				}
				sort = Search.CommonFields(images, false, false, true);
				SortByList.Items.Clear();
				if (sort != null)
				{
					int titleidx = 0;
					for (int i = 0; i < sort.Length; i++)
					{
						string name = sort[i].GetFieldName();
						string label = sort[i].Label;
						if (label.Length > 40)
							label = label.Substring(0, 37) + "...";
						SortByList.Items.Add(new ListItem(label, i.ToString()));						
						if ((titleidx == 0 && sort[i].IsDC() && name.ToLower() == "title") ||
							(sort[i].Name == preferredsortbyfield))
							titleidx = i;
					}
					images = Search.Sort(sort[titleidx], images);					
					SortByList.SelectedIndex = titleidx;
				}
				else
					SortBySpan.Visible = false;
				if (Session["CurrentSlideshow"] != null)
				{
					Slideshow show = Slideshow.GetByID((int)Session["CurrentSlideshow"]);
					if (show != null)
					{
						try
						{
							Slide[] slides = show.GetSlides();
							inslideshow = new ImageIdentifier[slides.Length];
							for (int i = 0; i < slides.Length; i++)
								inslideshow[i] = slides[i].ImageID;
							inslideshowtitle = show.Title;
						}
						catch
						{
							inslideshow = null;
							inslideshowtitle = null;
						}
					}
				}
			}
		}

		protected override void LoadViewState(object savedState) 
		{
			if (savedState != null)
			{
				base.LoadViewState(savedState);
				currentpage = (int)ViewState["currentpage"];
				totalpages = (int)ViewState["totalpages"];
				numrecords = (int)ViewState["numrecords"];
				inslideshowtitle = (string)ViewState["inslideshowtitle"];
				inslideshow = (ImageIdentifier[])ViewState["inslideshow"];
				editimagenotes = (ImageIdentifier)ViewState["editimagenotes"];
				sort = (SearchField[])ViewState["sort"];
				ids = (Hashtable)ViewState["ids"];
			}
		}

		protected override object SaveViewState()
		{
			ViewState["currentpage"] = currentpage;
			ViewState["totalpages"] = totalpages;
			ViewState["numrecords"] = numrecords;
			ViewState["inslideshowtitle"] = inslideshowtitle;
			ViewState["inslideshow"] = inslideshow;
			ViewState["editimagenotes"] = editimagenotes;
			ViewState["sort"] = sort;
			ViewState["ids"] = ids;
			return base.SaveViewState();
		}

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.RecordsPerPageList.SelectedIndexChanged += new System.EventHandler(this.RecordsPerPageList_SelectedIndexChanged);
			this.SortByList.SelectedIndexChanged += new System.EventHandler(this.SortByList_SelectedIndexChanged);
			this.ViewModeList.SelectedIndexChanged += new System.EventHandler(this.ViewModeList_SelectedIndexChanged);
			this.BackLinkButton.Click += new System.EventHandler(this.BackLinkButton_Click);
			this.SelectAllOnPageLinkButton.Click += new System.EventHandler(this.SelectAllOnPageLinkButton_Click);
			this.FilterButton.Click += new System.EventHandler(this.FilterButton_Click);
			this.FirstPageButton.Click += new System.EventHandler(this.FirstPageButton_Click);
			this.PrevPageButton.Click += new System.EventHandler(this.PrevPageButton_Click);
			this.NextPageButton.Click += new System.EventHandler(this.NextPageButton_Click);
			this.LastPageButton.Click += new System.EventHandler(this.LastPageButton_Click);
			this.R.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.R_ItemCommand);
			this.FirstPageButton2.Click += new System.EventHandler(this.FirstPageButton_Click);
			this.PrevPageButton2.Click += new System.EventHandler(this.PrevPageButton_Click);
			this.NextPageButton2.Click += new System.EventHandler(this.NextPageButton_Click);
			this.LastPageButton2.Click += new System.EventHandler(this.LastPageButton_Click);
			this.SaveSearchButton.Click += new System.EventHandler(this.SaveSearchButton_Click);
			this.Load += new System.EventHandler(this.Page_Load);
			this.PreRender += new System.EventHandler(this.result_PreRender);

		}
		#endregion

		private void FirstPageButton_Click(object sender, System.EventArgs e)
		{
			currentpage = 1;
		}

		private void PrevPageButton_Click(object sender, System.EventArgs e)
		{
			if (currentpage > 1)
				currentpage--;
		}

		private void NextPageButton_Click(object sender, System.EventArgs e)
		{
			if (currentpage < totalpages)
				currentpage++;
		}

		private void LastPageButton_Click(object sender, System.EventArgs e)
		{
			currentpage = totalpages;
		}

		private void RecordsPerPageList_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			if (user != null && !(user is AnonymousUser))
			{
				Properties props = Properties.GetProperties(user);
				props.Set("recordsperpage", RecordsPerPageList.SelectedItem.Value);
			}
			totalpages = (images.Length - 1) / 
				Int32.Parse(RecordsPerPageList.SelectedItem.Value) + 1;
			currentpage = 1;
		}

		private ImageIdentifier[] Paging(ImageIdentifier[] i, int pagesize, ref int page)
		{
			if (i == null || i.Length == 0)
				return new ImageIdentifier[0];
			if (pagesize < 1)
				pagesize = 1;
			if (page < 0)
				page = 0;
			int lastpage = i.Length / pagesize;
			if (page > lastpage)
				page = lastpage;
			ImageIdentifier[] r = new ImageIdentifier[page == lastpage ? i.Length - pagesize * lastpage : pagesize];
			for (int j = 0; j < r.Length; j++)
				r[j] = i[page * pagesize + j];
			return r;
		}
		
		private void result_PreRender(object sender, System.EventArgs e)
		{
			if (images == null || images.Length == 0)
				Response.Redirect("addimages.aspx"); 
			// get selected images again, in case the session object has been modified
			// in the meantime by the SelectionStatus user control
			selectedImages = Session["SelectedImages"] as ArrayList;
			if (selectedImages == null)
				selectedImages = new ArrayList();
			numrecords = images.Length;
			totalpages = (images.Length - 1) / Int32.Parse(RecordsPerPageList.SelectedItem.Value) + 1;
			int c = currentpage - 1;
			ImageIdentifier[] i = Paging(images, Int32.Parse(RecordsPerPageList.SelectedItem.Value), ref c);
//			PersonalCollection coll = PersonalCollection.GetPersonalCollection();
//			personalimageinfo = coll.GetPersonalImageInfo(i);
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			annotations = Orciid.Core.Image.GetAnnotations(user, i);
			imageobjects = Orciid.Core.Image.GetByID(i);
			foreach (Orciid.Core.Image imgchk in imageobjects)
				if (imgchk != null && 
					((imgchk.RecordStatus & ImageRecordStatus.StubOnly) == ImageRecordStatus.StubOnly))
				{
					ShowWarning(GetLocalString(this, "ImageStubWarning", 
						"Some image records are still being downloaded in the background. " +
						"Medium and full size images may not be available yet."));
					break;
				}
			if (user != null)
			{
				FavoritesCollection fc = FavoritesCollection.GetFavoritesCollection();
				hasfavorites = (fc != null && Orciid.Core.User.HasPrivilege(
					Privilege.ReadCollection, fc, user));
				if (hasfavorites)
					favorites = user.GetFavoriteImages();
			}
			else
				hasfavorites = false;
			hasRelatedImages = Analysis.ImageHasRelatedImages(i, (user != null ? user.ID : 0));
			inSlideshowCount = Analysis.GetImageInSlideshowCount(i);
			R.DataSource = i;
			RecordDisplayCounter = 0;
			DataBind();
			currentpage = c + 1;
			Session["SelectedImages"] = selectedImages;
			ResultPageOptions options = (ResultPageOptions)Session["LastSearchResult"];
			options.images = images;
			Session["LastSearchResult"] = options;
			SaveSearchDiv.Visible = (options.returnurl == "search.aspx" && user != null && user.ID > 0);
		}

		private Orciid.Core.Image GetImageOnPage(ImageIdentifier id)
		{
			foreach (Orciid.Core.Image img in imageobjects)
				if (img != null && img.ID == id)
					return img;
			return null;
		}
		
		protected string GetImageIdentifier(object o)
		{
			Orciid.Core.Image img = GetImageOnPage((ImageIdentifier)o);
			if (img != null)
				return img.ID.ToString();
			else
				return "0:0";
		}

		protected string GetPopupUrl(object o)
		{
			Orciid.Core.Image img = GetImageOnPage((ImageIdentifier)o);
			if (img != null)
			{
				if (img.IsExtendedResource())
				{
					ExtendedResource extres = img.GetExtendedResource();
					string med = (extres != null ? extres.GetImageResource(ImageSize.Medium) : null);
					if (med != null && med.Length > 0)
						return String.Format("javascript:popupviewer('{0}');", img.ID.ToString());
					else
						return "javascript:;";
				}
				else
					return String.Format("javascript:popupviewer('{0}');", img.ID.ToString());
			}
			else
				return "javascript:;";
		}

		private void SortByList_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			currentpage = 1;
			int idx = Int32.Parse(SortByList.SelectedItem.Value);
			if (sort != null && sort.Length > idx)
			{
				images = Search.Sort(sort[idx], images);
				ResultPageOptions options = (ResultPageOptions)Session["LastSearchResult"];
				options.images = images;
				Session["LastSearchResult"] = options;
				Orciid.Core.User user = Orciid.Core.User.CurrentUser();
				if (user != null && !(user is AnonymousUser))
				{
					Properties props = Properties.GetProperties(user);
					props.Set("sortbyfield", sort[idx].Name);
				}
			}
		}

		private bool CompactView
		{
			get
			{
				return ViewModeList.SelectedItem.Value == "none";
			}
		}

		protected void DataBindThumbnail(object sender, System.EventArgs e)
		{
			System.Web.UI.WebControls.Image thumbnail = sender as System.Web.UI.WebControls.Image;
			RepeaterItem item = thumbnail.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Orciid.Core.Image img = GetImageOnPage((ImageIdentifier)((RepeaterItem)thumbnail.Parent).DataItem);
			if (img != null)
			{
				thumbnail.ImageUrl = String.Format("getimage.aspx?cid={0}&res={1}&format=T", 
					img.CollectionID, HttpUtility.UrlEncode(img.Resource));
				thumbnail.Attributes["title"] = GetImageTitle(img);
			}
			else
				thumbnail.ImageUrl = "getimage.aspx?id=0&cid=0&format=T";
		}

		private string GetImageTitle(Orciid.Core.Image image)
		{
			Collection coll = Collection.GetByID(image.ID.CollectionID);
			if (coll == null)
				return "";
			string title = GetImageDataValue(image, coll, "title");
			if (title.Length == 0)
				title = GetLocalString(this, "UnknownTitleLabel", "[unknown title]");
			string creator = GetImageDataValue(image, coll, "creator");
			if (creator.Length > 0)
				creator = ", " + creator;
			string date = GetImageDataValue(image, coll, "date");
			if (date.Length > 0)
				date = ", " + date;
			string medium = GetImageDataValue(image, coll, "format.medium");
			if (medium.Length == 0)
				medium = GetImageDataValue(image, coll, "format");
			if (medium.Length > 0)
				medium = " (" + medium + ")";
			return title + date + medium + creator;
		}

		private string GetImageDataValue(Orciid.Core.Image image, Collection coll, string dcname)
		{
			Field field = coll.GetField(dcname, true, true);
			if (field == null)
				return "";
			FieldData data = image[field];
			if (data == null || data.Count == 0)
				return "";
			return data[0];
		}

		protected void DataBindImageRecord(object sender, System.EventArgs e)
		{
			ArrayList extrainfo = new ArrayList();
			PlaceHolder placeholder = sender as PlaceHolder;
			RepeaterItem item = placeholder.Parent as RepeaterItem;
//			PersonalImageInfo info = personalimageinfo[item.ItemIndex];
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Orciid.Core.Image image = GetImageOnPage((ImageIdentifier)((RepeaterItem)placeholder.Parent).DataItem);
			if (image != null && image.UserName != null)
				extrainfo.Add(new ImageRecordDisplay.DataEntry(
					GetLocalString(this, "OwnerLabel", "Owner"), 
					image.UserName,
					true));
			if (editimagenotes != id)
			{
				string annotation = annotations[item.ItemIndex];
				if (annotation != null)
					extrainfo.Add(new ImageRecordDisplay.DataEntry(
						GetLocalString(this, "ImageNoteLabel", "Image Note"), annotation, true));
			}
			ViewMode viewmode = (ViewModeList.SelectedItem.Value == "long" ? ViewMode.Long : ViewMode.Short);			
			
			if (!CompactView)
			{
				if (image != null)
				{
					if (viewmode == ViewMode.Long && image.CreatedDate != DateTime.MinValue)
						extrainfo.Add(new ImageRecordDisplay.DataEntry(
							GetLocalString(this, "ImageAddedLabel", "Image added"), 
							image.ModifiedDate.ToShortDateString(), true));
					if (viewmode == ViewMode.Long && image.ModifiedDate != DateTime.MinValue)
						extrainfo.Add(new ImageRecordDisplay.DataEntry(
							GetLocalString(this, "ImageUpdatedLabel", "Image updated"), 
							image.ModifiedDate.ToShortDateString(), true));
				}
				if (viewmode == ViewMode.Long)
				{
					string url = Request.Url.GetLeftPart(UriPartial.Authority) + 
						Request.ApplicationPath + 
						(Request.ApplicationPath.EndsWith("/") ? "" : "/") + 
						"default.aspx?direct=image&id=" + id.ToString();
					extrainfo.Add(new ImageRecordDisplay.DataEntry(
						GetLocalString(this, "DirectLinkLabel", "Direct Link"), url, true));
					
					if (inSlideshowCount[item.ItemIndex] > 0)
					{
						extrainfo.Add(new ImageRecordDisplay.DataEntry(
							GetLocalString(this, "ImageUse", "Image Use"),
							String.Format("<a href=\"imageuse.aspx?id={0}\">", id.ToString()) +
							String.Format(GetLocalString(this, "ImageUseValue", "{0} slideshows"), 
							inSlideshowCount[item.ItemIndex]) + "</a>", false));
					}
				}
				UserControls.ImageRecordDisplay display = LoadControl("UserControls/ImageRecordDisplay.ascx") as UserControls.ImageRecordDisplay;
				display.DataSource = image;
				display.ViewMode = viewmode;
				display.EnableViewState = false;
				display.ExtraInfo = extrainfo;
				placeholder.Controls.Add(display);
				display.DataBind();
				if (image != null && image.IsExtendedResource())
				{
					Collection coll = Collection.GetByID(image.ID.CollectionID);
					ExtendedResource extres = image.GetExtendedResource();
					if (coll != null && extres.IsValid)
					{
						ArrayList records = new ArrayList();
						records.AddRange(extres.GetRecords(ImageSize.Medium));
						if (Orciid.Core.User.HasPrivilege(Privilege.FullSizedImages, coll))
							records.AddRange(extres.GetRecords(ImageSize.Full));
						foreach (ExtendedResource.Record record in records)
						{
							System.Web.UI.Control control = 
								Extensions.ExtendedResourceDisplay.GetControl(this, record);
							if (control != null)
							{
								placeholder.Controls.Add(control);
								placeholder.Controls.Add(new LiteralControl("<br />"));
							}
						}
					}
				}
			}
		}

		protected void DataBindFavoriteImage(object sender, System.EventArgs e)
		{
			CheckBox checkbox = sender as CheckBox;
			if (hasfavorites)
			{
				RepeaterItem item = checkbox.Parent.Parent as RepeaterItem;
				checkbox.Visible = (Orciid.Core.User.CurrentUser() != null);
				ImageIdentifier id = (ImageIdentifier)item.DataItem;
				Orciid.Core.Image img = GetImageOnPage(id);
				if (img != null)
				{
					if (favorites != null)
						foreach (ImageIdentifier f in favorites)
							if (f == id)
							{
								checkbox.Checked = true;
								break;
							}
				}
				else
					checkbox.Parent.Visible = false;
			}
			else
				checkbox.Parent.Visible = false;
		}

		protected void DataBindSelectImage(object sender, System.EventArgs e)
		{
			CheckBox checkbox = sender as CheckBox;
			RepeaterItem item = checkbox.Parent.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Orciid.Core.Image img = GetImageOnPage(id);
			ids[item.ItemIndex] = id;
			if (img != null && !img.IsExtendedResource() && 
				((PageTemplate.OrciidPage)Page).UserCanBuildSlideshows)
				checkbox.Checked = selectedImages.Contains(id);				
			else
				checkbox.Parent.Visible = false;
		}

		protected void DataBindShareImage(object sender, System.EventArgs e)
		{
			CheckBox checkbox = sender as CheckBox;
			RepeaterItem item = checkbox.Parent.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Orciid.Core.Image img = GetImageOnPage(id);
			Collection coll = Collection.GetByID(id.CollectionID);
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
//			PersonalImageInfo info = personalimageinfo[item.ItemIndex];
//			checkbox.Checked = (info.Status == ShareStatus.Shared);
//			checkbox.Parent.Visible = (info.Status != ShareStatus.NotSharable);
			checkbox.Checked = (img != null && img.IsShared);
			checkbox.Parent.Visible = (img != null && img.IsShareable && coll != null && 
				img.UserID == user.ID && Orciid.Core.User.HasPrivilege(Privilege.ShareImages, coll));
		}

		protected void DataBindSuggestImage(object sender, System.EventArgs e)
		{
			CheckBox checkbox = sender as CheckBox;
			RepeaterItem item = checkbox.Parent.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Orciid.Core.Image img = GetImageOnPage(id);
			Collection coll = Collection.GetByID(id.CollectionID);
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			//			PersonalImageInfo info = personalimageinfo[item.ItemIndex];
			//			checkbox.Checked = (info.Status == ShareStatus.Shared);
			//			checkbox.Parent.Visible = (info.Status != ShareStatus.NotSharable);
			checkbox.Checked = (img != null && img.IsSuggested);
			checkbox.Parent.Visible = (img != null && img.IsShareable && coll != null && 
				img.UserID == user.ID &&  Orciid.Core.User.HasPrivilege(Privilege.SuggestImages, coll));
			if (img != null && (img.Flags & ImageFlag.InclusionRefused) == ImageFlag.InclusionRefused)
			{
				checkbox.Parent.FindControl("j").Visible = true;
				checkbox.Text = GetLocalString(this, "SuggestAgainLabel", "Suggest again");
			}
		}

		protected void DataBindInSlideshowIndicator(object sender, System.EventArgs e)
		{
			System.Web.UI.WebControls.Image image = sender as System.Web.UI.WebControls.Image;
			RepeaterItem item = image.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			// Add indicator if image is already in slideshow
			if (inslideshow != null)
			{
				foreach (ImageIdentifier sid in inslideshow)
					if (id == sid)
					{
						image.Attributes["align"] = "right";
						image.Attributes["vspace"] = "7";
						image.ToolTip = String.Format(GetLocalString(this, "ImageInSlideshowTooltip",
							"This image is in slideshow '{0}'"), inslideshowtitle);
						image.Visible = true;
						SlideIconExplanation.Visible = true;
						break;
					}
			}
		}

		protected void DataBindOtherOwnerImage(object sender, System.EventArgs e)
		{
			System.Web.UI.WebControls.Image image = sender as System.Web.UI.WebControls.Image;
			RepeaterItem item = image.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Orciid.Core.Image i = GetImageOnPage(id);
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			if (i != null && i.UserName != null && (user == null || i.UserID != user.ID))
			{
				image.Attributes["align"] = "right";
				image.ToolTip = GetLocalString(this, "OtherUserSharedLabel", 
					"Another user shared this image");
				image.Visible = true;
			}
		}

		protected void DataBindEditButton(object sender, System.EventArgs e)
		{
			ImageButton button = sender as ImageButton;
			RepeaterItem item = button.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
//			PersonalImageInfo info = personalimageinfo[item.ItemIndex];
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			Orciid.Core.Image img = GetImageOnPage(id);
			if (img != null)
			{
				Collection coll = Collection.GetByID(id.CollectionID);
				if (coll != null && (!coll.IsReadOnly) &&
					((Orciid.Core.User.HasPrivilege(Privilege.ModifyImages, coll) &&
						img.UserID == 0) ||
					 (Orciid.Core.User.HasPrivilege(Privilege.PersonalImages, coll) &&
					  img.UserID == user.ID)))
				{
					button.ToolTip = GetLocalString(this, "EditLabel", "Edit");
					button.CommandArgument = id.ToString();
					button.Visible = true;
				}
			}
		}		

		protected void DataBindDeleteButton(object sender, System.EventArgs e)
		{
			ImageButton button = sender as ImageButton;
			RepeaterItem item = button.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Collection coll = Collection.GetByID(id.CollectionID);
//			PersonalImageInfo info = personalimageinfo[item.ItemIndex];
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			Orciid.Core.Image img = GetImageOnPage(id);
			if (img != null)
			{
				if (coll != null && (!coll.IsReadOnly) &&
					((Orciid.Core.User.HasPrivilege(Privilege.ModifyImages, coll) &&
						img.UserID == 0) ||
					 (Orciid.Core.User.HasPrivilege(Privilege.PersonalImages, coll) &&
					  img.UserID == user.ID)))
				{
					button.ToolTip = GetLocalString(this, "DeleteLabel", "Delete");
					button.CommandArgument = id.ToString();
					button.Attributes["onclick"] = "return confirm('" +
						EncodeJavaScriptString(GetLocalString(this, "DeleteConfirmation", 
						"Are you sure you want to delete this record?")) + "');";
					button.Visible = true;
				}
			}
		}

		protected void DataBindDownloadButton(object sender, System.EventArgs e)
		{
			HyperLink link = sender as HyperLink;
			RepeaterItem item = link.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Collection coll = Collection.GetByID(id.CollectionID);
			Orciid.Core.Image img = GetImageOnPage(id);
			if (img != null)
			{
				string version = 
					(Orciid.Core.User.HasPrivilege(Privilege.FullSizedImages, coll) ? "F" : "M");
				if (img.IsExtendedResource())
				{
					ExtendedResource extres = img.GetExtendedResource();
					if (extres != null && extres.IsValid)
					{
						if (version == "F")
							if (extres.GetImageResource(ImageSize.Full) == "")
								version = "M";
						if (version == "M")
							if (extres.GetImageResource(ImageSize.Medium) == "")
								version = "";
					}
				}
				if (version.Length > 0)
				{
					link.NavigateUrl = String.Format("getimage.aspx?id={0}&cid={1}&format={2}",
						id.ID, id.CollectionID, version);
					link.ToolTip = GetLocalString(this, "DownloadLabel", "Download");
					link.Visible = true;
				}
			}
		}

		protected void DataBindXMLButton(object sender, System.EventArgs e)
		{
// FogBugz case 149			
/*			HyperLink link = sender as HyperLink;
			RepeaterItem item = link.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Collection coll = Collection.GetByID(id.CollectionID);
			Orciid.Core.Image img = GetImageOnPage(id);
			if (img != null)
			{
				if (Orciid.Core.User.HasPrivilege(Privilege.PackageImages, coll))
				{
					link.NavigateUrl = "about:blank";
					link.ToolTip = "Download XML";
					link.Visible = true;
				}
			}
*/		}

		protected void DataBindRelatedImagesButton(object sender, System.EventArgs e)
		{
			LinkButton button = sender as LinkButton;
			RepeaterItem item = button.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Orciid.Core.Image img = GetImageOnPage(id);
			button.CommandArgument = id.ToString();
			button.Visible = (img != null && hasRelatedImages[item.ItemIndex]);
		}

		protected void DataBindAcceptLinkButton(object sender, System.EventArgs e)
		{
			LinkButton button = sender as LinkButton;
			RepeaterItem item = button.Parent.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Collection coll = Collection.GetByID(id.CollectionID);
			Orciid.Core.Image img = GetImageOnPage(id);
			button.CommandArgument = id.ToString();
			button.Parent.Visible = (img != null && coll != null &&
				Orciid.Core.User.HasPrivilege(Privilege.ModifyImages, coll) &&
				(img.Flags & ImageFlag.InclusionSuggested) == ImageFlag.InclusionSuggested);
		}

		protected void DataBindRejectLinkButton(object sender, System.EventArgs e)
		{
			LinkButton button = sender as LinkButton;
			RepeaterItem item = button.Parent.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			button.CommandArgument = id.ToString();
			// visibility for section handled in DataBindAcceptLinkButton
		}

		protected void DataBindNotesButton(object sender, System.EventArgs e)
		{
			ImageButton button = sender as ImageButton;
			RepeaterItem item = button.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			Collection coll = Collection.GetByID(id.CollectionID);
			Orciid.Core.Image img = GetImageOnPage(id);
			if (img != null)
			{
				if (Orciid.Core.User.HasPrivilege(Privilege.AnnotateImages, coll))
				{
					button.ToolTip = GetLocalString(this, "ImageNotesLabel", "Image Notes");
					button.CommandArgument = id.ToString();
					button.Visible = true;
				}
			}
		}

		protected void DataBindImageNotesTextBox(object sender, System.EventArgs e)
		{
			TextBox textbox = sender as TextBox;
			Panel panel = textbox.Parent as Panel;
			RepeaterItem item = panel.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)item.DataItem;
			if (editimagenotes == id)
			{
				panel.Visible = true;
				textbox.Text = annotations[item.ItemIndex];
				ScrollToImageNotesPlaceHolder.Controls.Add(new LiteralControl(String.Format(@"
<script language='javascript' type='text/javascript'>
	if (!window.location.hash) window.location.hash = 'anchor{0}';
</script>", id)));
			}
		}

		protected void DataBindResultSeparator(object sender, System.EventArgs e)
		{
			RecordDisplayCounter++;
			PlaceHolder control = sender as PlaceHolder;
			if (control != null && CompactView && (RecordDisplayCounter % 5 != 0))
				control.Visible = false;				
		}
		
		protected void SelectCheckBoxChanged(object sender, System.EventArgs e)
		{
			CheckBox checkbox = sender as CheckBox;
			RepeaterItem item = checkbox.Parent.Parent as RepeaterItem;
			ImageIdentifier id = (ImageIdentifier)ids[item.ItemIndex];
			Collection coll = Collection.GetByID(id.CollectionID);
			Orciid.Core.Image img = Orciid.Core.Image.GetByID(id);
			if (checkbox.Checked)
			{
				if (!selectedImages.Contains(id))
					selectedImages.Add(id);
				if (coll is IRemoteCollection)
					((IRemoteCollection)coll).PrecacheImage(img);
			}
			else
				selectedImages.Remove(id);
		}

		protected void FavoriteCheckBoxChanged(object sender, System.EventArgs e)
		{
			CheckBox checkbox = sender as CheckBox;
			RepeaterItem item = checkbox.Parent.Parent as RepeaterItem;
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			ImageIdentifier id = (ImageIdentifier)ids[item.ItemIndex];
			Collection coll = Collection.GetByID(id.CollectionID);
			Orciid.Core.Image img = Orciid.Core.Image.GetByID(id);
			if (user != null)
			{
				if (checkbox.Checked)
				{
					user.AddFavoriteImages(id);
					if (coll is IRemoteCollection)
						((IRemoteCollection)coll).PrecacheImage(img);
				}
				else
					user.DeleteFavoriteImages(id);
			}
		}

		protected void ShareCheckBoxChanged(object sender, System.EventArgs e)
		{
			CheckBox checkbox = sender as CheckBox;
			RepeaterItem item = checkbox.Parent.Parent as RepeaterItem;
			//Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			ImageIdentifier id = (ImageIdentifier)ids[item.ItemIndex];
			Collection coll = Collection.GetByID(id.CollectionID);
			coll.ShareImage(checkbox.Checked, id);
		}

		protected void SuggestCheckBoxChanged(object sender, System.EventArgs e)
		{
			CheckBox checkbox = sender as CheckBox;
			RepeaterItem item = checkbox.Parent.Parent as RepeaterItem;
			//Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			ImageIdentifier id = (ImageIdentifier)ids[item.ItemIndex];
			Collection coll = Collection.GetByID(id.CollectionID);
			coll.SuggestImageForInclusion(checkbox.Checked, id);
		}

		public override string GetHighlightedMenuItem()
		{
			return "Resources_BrowseSearch";
		}

		protected override bool CheckUserPrivileges(Orciid.Core.User user)
		{
			return true;
		}

/*		private void AddSlidesButton_Click(object sender, System.EventArgs e)
		{
			Response.Redirect("addslides.aspx"); 
		}

		private void BackToSearchButton_Click(object sender, System.EventArgs e)
		{
			Response.Redirect("search.aspx"); 
		}

		private void BackToBrowseButton_Click(object sender, System.EventArgs e)
		{
			Response.Redirect("browse.aspx"); 
		}
*/
		private void R_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
		{
			if (e.CommandName == "edit")
			{
				ImageIdentifier id = ImageIdentifier.Parse(e.CommandArgument.ToString());
				Response.Redirect(String.Format("editor.aspx?id={0}&return={1}", 
					id, Server.UrlEncode(String.Format("result.aspx?page={0}", currentpage))));
			}
			else if (e.CommandName == "delete")
			{
				ImageIdentifier id = ImageIdentifier.Parse(e.CommandArgument.ToString());
				Orciid.Core.Image image = Orciid.Core.Image.GetByID(id);
				if (image != null)
					image.Delete();
				selectedImages.Remove(id);
				ArrayList i = new ArrayList(images);
				i.Remove(id);
				images = (ImageIdentifier[])i.ToArray(typeof(ImageIdentifier));
			}
			else if (e.CommandName == "notes")
			{
				editimagenotes = ImageIdentifier.Parse(e.CommandArgument.ToString());
			}
			else if (e.CommandName == "related")
			{
				ImageIdentifier id = ImageIdentifier.Parse(e.CommandArgument.ToString());
				Orciid.Core.User user = Orciid.Core.User.CurrentUser();
				ImageIdentifier[] related = Analysis.GetRelatedImages(id, (user != null ? user.ID : 0));
				if (related != null && related.Length > 0)
				{
					Session["LastSearchResult"] = new ResultPageOptions(
						GetLocalString(this, "RelatedImagesHeading", "Related Images"), 
						null, null, related);
					Response.Redirect("result.aspx"); 
				}
			}
			else if (e.CommandName == "accept")
			{
				ImageIdentifier id = ImageIdentifier.Parse(e.CommandArgument.ToString());
				Orciid.Core.Image img = Orciid.Core.Image.GetByID(id);
				User owner = Orciid.Core.User.GetByID(img.UserID);
				Collection coll = Collection.GetByID(id.CollectionID);
				if (owner != null && coll != null)
					coll.AcceptImageForInclusion(owner, id);
				Response.Redirect(String.Format("editor.aspx?id={0}&return={1}", 
					id, Server.UrlEncode(String.Format("result.aspx?page={0}", currentpage))));
			}
			else if (e.CommandName == "reject")
			{
				ImageIdentifier id = ImageIdentifier.Parse(e.CommandArgument.ToString());
				Orciid.Core.Image img = Orciid.Core.Image.GetByID(id);
				User owner = Orciid.Core.User.GetByID(img.UserID);
				Collection coll = Collection.GetByID(id.CollectionID);
				if (owner != null && coll != null)
					coll.RejectImageForInclusion(owner, id);
				ArrayList i = new ArrayList(images);
				i.Remove(id);
				images = (ImageIdentifier[])i.ToArray(typeof(ImageIdentifier));
				if (images.Length == 0)
					BackLinkButton_Click(null, null);
			}
		}

		private void BackLinkButton_Click(object sender, System.EventArgs e)
		{
			string url = ((ResultPageOptions)Session["LastSearchResult"]).returnurl;
			if (url != null && url.Length > 0)
				Response.Redirect(url);
		}

		protected void UpdateImageNotes(object sender, System.EventArgs e)
		{
			if (editimagenotes.ID == 0 || editimagenotes.CollectionID == 0)
				return;
			TextBox textbox = ((LinkButton)sender).Parent.FindControl("notes") as TextBox;
			Orciid.Core.Image image = Orciid.Core.Image.GetByID(editimagenotes);
			Collection coll = Collection.GetByID(image.CollectionID);
			if (image != null)
			{
				if (textbox.Text == null || textbox.Text.Length == 0)
					image.SetAnnotation(null);
				else
					image.SetAnnotation(textbox.Text);
				if (coll is IRemoteCollection)
					((IRemoteCollection)coll).PrecacheImage(image);
			}
			editimagenotes.ID = 0;
			editimagenotes.CollectionID = 0;
		}

		protected void CancelImageNotes(object sender, System.EventArgs e)
		{
			editimagenotes.ID = 0;
			editimagenotes.CollectionID = 0;
		}

		private void SaveSearchButton_Click(object sender, System.EventArgs e)
		{
			string title = SaveSearchTextBox.Text;
			if (title == null || title.Length == 0)
			{
				ShowError(GetLocalString(this, "SavedSearchTitleMissing", 
					"Please enter a title for this search."));
			}
			else
			{
				Orciid.Core.User user = Orciid.Core.User.CurrentUser();
				SavedSearch.Create(user, title, 
					new Search.SearchParameters((string)Session["LastSearch"]));
				ShowInformation(GetLocalString(this, "SearchSavedMessage", "Search saved."));
			}
		}

		private void SelectAllOnPageLinkButton_Click(object sender, System.EventArgs e)
		{
			ImageIdentifier[] i = new ImageIdentifier[ids.Count];
			ids.Values.CopyTo(i, 0);
			Orciid.Core.Image[] imgs = Orciid.Core.Image.GetByID(i);
			foreach (ImageIdentifier id in ids.Values)
				if (!selectedImages.Contains(id))
				{
					Orciid.Core.Image img = null;
					foreach (Orciid.Core.Image a in imgs)
						if (a.ID == id)
						{
							img = a;
							break;
						}
					if (img != null && !img.IsExtendedResource())
					{
						selectedImages.Add(id);		
						Collection coll = Collection.GetByID(img.CollectionID);
						if (coll is IRemoteCollection)
							((IRemoteCollection)coll).PrecacheImage(img);
					}
				}
		}

		private void FilterButton_Click(object sender, System.EventArgs e)
		{
			string keyword = FilterTextBox.Text;
			if (keyword == "")
				return;

			Search.SearchParameters parameters = new Search.SearchParameters();

			Hashtable collids = new Hashtable();
			foreach (ImageIdentifier imgid in images)
				collids[imgid.CollectionID] = 1;
			foreach (int collid in collids.Keys)
			{
				Collection coll = Collection.GetByID(collid);
				if (coll != null)
					parameters.collections.Add(coll);
			}

			// add the two virtual collections used to access personal images
			// otherwise, filtering never finds personal images
			// (bug 264)

			parameters.collections.Add(PersonalImagesCollection.GetPersonalImagesCollection());
			parameters.collections.Add(SharedImagesCollection.GetSharedImagesCollection());

//			IDCondition idcond = new IDCondition();
//			idcond.ImageIdentifiers = images;
//			parameters.conditions.Add(idcond);

			foreach (string s in TextCondition.SplitTerms(keyword))
			{
				string ts = s.Trim();
				if (ts.Length > 0)
				{
					KeywordCondition c = new KeywordCondition();
					try
					{
						c.Keyword = ts;
						parameters.conditions.Add(c);
					}
					catch
					{
						parameters.warnings.Add(String.Format(
							GetLocalString(this, "InvalidKeyword", "{0} is not a valid keyword"), ts));
					}
				}
			}

			if (parameters.collections.Count == 0)
			{
				parameters.warnings.Add(GetLocalString(this, "NoCollections", "No collections were specified."));
			}
			else
			{					
				try
				{
					ImageIdentifier[] imgs = Search.Execute(parameters, 
						Configuration.Instance.GetInt("ui.maxsearchresults"), false, images);
					if (imgs == null || imgs.Length == 0)
						parameters.warnings.Add(GetLocalString(this, "NoImages", 
						"No matching image records were found."));
					else
						Session["LastSearchResult"] = new ResultPageOptions(
							GetLocalString(this, "SearchResults", "Search Results"), 
							null, 
							null, 
							imgs);
				}
				catch (TooManySearchResultsException)
				{
					parameters.warnings.Add(GetLocalString(this, "TooManyImages",
						"Too many images match the specified criteria. " +
						"Please change your criteria to be more specific."));
				}
				catch (CoreException ex)
				{
					parameters.warnings.Add(ex.Message);
				}
			}
			if (parameters.warnings.Count == 0)
				Response.Redirect("result.aspx"); 
			else
				foreach (string s in parameters.warnings)
					ShowWarning(s);
		}

		private void ViewModeList_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			Orciid.Core.User user = Orciid.Core.User.CurrentUser();
			if (user != null && !(user is AnonymousUser))
			{
				Properties props = Properties.GetProperties(user);
				props.Set("resultviewmode", ViewModeList.SelectedItem.Value);
			}
		}

		protected int CurrentPage
		{
			get
			{
				return currentpage;
			}
		}

		protected int TotalPages
		{
			get
			{
				return totalpages;
			}
		}

		protected int NumRecords
		{
			get
			{
				return numrecords;
			}
		}

		protected string InSlideshowTitle
		{
			get
			{
				return inslideshowtitle;
			}
		}
	}
}
