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.Web.Mail;
using System.Text.RegularExpressions;
using Orciid.Core;

namespace Orciid
{
	public class _default : PageTemplate.OrciidPage
	{
		protected System.Web.UI.WebControls.TextBox PasswordTextBox;
		protected System.Web.UI.WebControls.TextBox UsernameTextBox;
		protected System.Web.UI.WebControls.RequiredFieldValidator UsernameRequiredFieldValidator;
		protected System.Web.UI.WebControls.RequiredFieldValidator PasswordRequiredFieldValidator;
		protected System.Web.UI.WebControls.Button GuestLoginButton;
		protected System.Web.UI.WebControls.Button LoginButton;
		protected System.Web.UI.HtmlControls.HtmlGenericControl AnnouncementDiv;
		protected System.Web.UI.HtmlControls.HtmlGenericControl RequestAccountDiv;
		private string directlinkurl = null;
		private int directlinkid = 0;
		protected System.Web.UI.WebControls.TextBox FirstNameTextBox;
		protected System.Web.UI.WebControls.TextBox LastNameTextBox;
		protected System.Web.UI.WebControls.TextBox EmailAddressTextBox;
		protected System.Web.UI.WebControls.Button CreateAccountButton;
		protected System.Web.UI.WebControls.Label AccountCreatedLabel;
		protected System.Web.UI.HtmlControls.HtmlGenericControl WelcomeHeading;
		protected System.Web.UI.HtmlControls.HtmlGenericControl UserNameSpan;
		protected System.Web.UI.HtmlControls.HtmlGenericControl PasswordSpan;
		protected System.Web.UI.WebControls.PlaceHolder LanguagesPlaceHolder;
		protected System.Web.UI.HtmlControls.HtmlGenericControl GuestLoginLabelSpan;
		protected System.Web.UI.HtmlControls.HtmlTableCell GuestLoginArea;
		private string directlinkresource = null;
	
		protected override void LoadViewState(object savedState) 
		{
			if (savedState != null)
			{
				base.LoadViewState(savedState);
				directlinkurl = (string)ViewState["directlinkurl"];
				directlinkid = (int)ViewState["directlinkid"];
				directlinkresource = (string)ViewState["directlinkresource"];
			}
		}

		protected override object SaveViewState()
		{
			ViewState["directlinkurl"] = directlinkurl;
			ViewState["directlinkid"] = directlinkid;
			ViewState["directlinkresource"] = directlinkresource;
			return base.SaveViewState();
		}

		private bool HandleDirectLinkToResource(int id, string res)
		{
			Collection coll = Collection.GetByID(id);
			if (coll == null)
				return false;
			ArrayList image = coll.GetImagesByResource(res);
			if (image == null || image.Count != 1)
				return false;
			Session["LastSearchResult"] = new ResultPageOptions(
				GetLocalString(this, "DirectLinkResults", "Direct Link Results"), 
				null, null, 
				new ImageIdentifier[] { ((Orciid.Core.Image)image[0]).ID });
			directlinkurl = "result.aspx";
			return true;
		}

		private void HandleDirectLink(Orciid.Core.User user, string direct, string id, string res,
			bool tryguest)
		{
			directlinkurl = null;
			if (direct == "image")
			{
				#region Image
				ImageIdentifier imgid = new ImageIdentifier(0, 0);
				if (res == null)
				{
					try
					{
						imgid = ImageIdentifier.Parse(id);
					}
					catch
					{
					}
					if (imgid.CollectionID != 0 && imgid.ID != 0)
					{
						Session["LastSearchResult"] = new ResultPageOptions(
							GetLocalString(this, "DirectLinkResults", "Direct Link Results"), 
							null, null, new ImageIdentifier[] { imgid });
						directlinkurl = "result.aspx";
						if (user == null && GuestLoginButton.Visible && tryguest)
						{
							// try if guest is authorized
							Orciid.Core.User u = Orciid.Core.AnonymousUser.User;
							u.Activate(Request.UserHostAddress);
							Collection coll = Collection.GetByID(imgid.CollectionID);
							if (coll != null)
								GuestLoginButton_Click(null, null);
							else
								GuestLoginButton.Visible = false;
						}
					}
				}
				else
				{
					try
					{
						directlinkid = Int32.Parse(id);
						directlinkresource = res;
					}
					catch
					{
						return;
					}
					if (user == null && GuestLoginButton.Visible && tryguest)
					{
						// try if guest is authorized
						Orciid.Core.User u = Orciid.Core.AnonymousUser.User;
						u.Activate(Request.UserHostAddress);
						if (HandleDirectLinkToResource(directlinkid, directlinkresource))
							GuestLoginButton_Click(null, null);
						else 
							GuestLoginButton.Visible = false;
					}
					else if (user != null)
						HandleDirectLinkToResource(directlinkid, directlinkresource);
				}
				#endregion
			}
			else if (direct == "slideshow")
			{
				#region Slideshow
				int ssid = 0;
				try
				{
					ssid = Int32.Parse(id);
				}
				catch
				{
				}
				directlinkurl = "directlink.aspx";
				Response.Cookies.Add(new HttpCookie("directlink",
					String.Format("slideshowpassword.aspx?id={0}&url={1}", 
					ssid, Server.UrlEncode(String.Format("slideshowviewer.aspx?" +
					"ssid={0}&url=viewslideshows.aspx&label=" + 
					Server.UrlEncode(GetLocalString(this, "SlideshowList", "SLIDESHOW LIST")), 
					ssid)))));
				if (user == null && GuestLoginButton.Visible && tryguest)
				{
					// try if guest is authorized
					Orciid.Core.User u = Orciid.Core.AnonymousUser.User;
					u.Activate(Request.UserHostAddress);
					Slideshow show = Slideshow.GetByID(ssid);
					if (show != null)
						GuestLoginButton_Click(null, null);
					else
						GuestLoginButton.Visible = false;
				}
				#endregion
			}
			else if (direct == "downloads")
			{
				#region Downloads
				string checkiv = Request.QueryString["checkiv"];
				if (checkiv != null && checkiv.Length > 0)
				{
					directlinkurl = "directlink.aspx";
					Response.Cookies.Add(new HttpCookie("directlink", 
						"downloads.aspx?checkiv=" + Server.UrlEncode(checkiv)));
				}
				else
					directlinkurl = "downloads.aspx";
				#endregion
			}
		}

		private void Page_Load(object sender, System.EventArgs e)
		{
			if (Configuration.Instance.ContainsKey("ui.language"))
			{
				Regex regex = new Regex("^([a-z][a-z]-[A-Z][A-Z]) (.+)$");
				foreach (string s in Configuration.Instance.GetMultiString("ui.language"))
				{
					Match match = regex.Match(s);
					if (match.Success)
					{
						LinkButton button = new LinkButton();
						button.Command += new CommandEventHandler(LanguageButton_Command);
						button.CommandName = "language";
						button.CommandArgument = match.Groups[1].Value;
						button.Text = match.Groups[2].Value;
						button.CausesValidation = false;
						if (LanguagesPlaceHolder.Controls.Count > 0)
							LanguagesPlaceHolder.Controls.Add(new LiteralControl(" &nbsp; "));
						LanguagesPlaceHolder.Controls.Add(button);
					}
				}
			}
			
			Orciid.Core.User ssouser = null;
			if (!IsPostBack)
			{
				Properties props = Properties.GetSystemProperties();
				GuestLoginButton.Visible = (props.GetAsInt("allowguest", 0) == 1);
				GuestLoginArea.Visible = GuestLoginButton.Visible;
				ssouser = CheckSingleSignOn();
			}
			string direct = Request.QueryString["direct"];
			string id = Request.QueryString["id"];
			string res = Request.QueryString["res"];
			Orciid.Core.User user = Session["CurrentUser"] as Orciid.Core.User;
			if (direct != null && direct.Length > 0)
				HandleDirectLink(ssouser == null ? user : null, direct, id, res, ssouser == null);
			if (user != null && ssouser == null)
			{
				if (directlinkurl != null)
					Response.Redirect(directlinkurl);
				else
				{
					string page = "announcements";
					Properties props = Properties.GetProperties(user);
					page = props.Get("uistartpage", page);				
					Response.Redirect(page + ".aspx"); 
				}
			}
			if (ssouser != null)
			{
				if (directlinkresource != null)
					HandleDirectLinkToResource(directlinkid, directlinkresource);
				ProceedToAgreements();
			}
#if DEMO
#warning Compiling for Demo site
			RequestAccountDiv.Visible = true;
			AnnouncementDiv.Visible = !IsPostBack;
			AnnouncementDiv.InnerHtml = @"
<P>To use the demo, you must request a user account below.<STRONG> User accounts 
and personal content are removed after seven days of inactivity.</STRONG></P>
<P>MDID2 is still under development, so you may encounter an occasional bug or 
inconsistency in this demo. Please feel free to report any problems and send 
your comments and suggestions to <A href='mailto:mdid@jmu.edu'>mdid@jmu.edu</A>. 
We sincerely appreciate your interest and your feedback.</P>
<P>The MDID2 software has been released in July 2004 under an open 
source license. Find more information&nbsp;at <A href='http://mdid.org/'>mdid.org</A>.</P>
<H2>Sample collections in this demo</H2>
<P>We are very grateful to the content providers who have provided images for the 
sample collections in this demo:</P>
<UL>
<LI>
<A href='http://arthist.cla.umn.edu/aict/html/'>AICT, Art Images for College 
Teaching</A>, Allan T. Kohl
<LI>
<A href='http://www.saskia.com/'>Saskia, Ltd. Cultural Documentation</A>
<LI>
<A href='http://web.jmu.edu/mars'>Madison Art Collection</A>, James Madison 
University
<LI>
JMU Photography Collection, <A href='http://www.jmu.edu/photography/'>Photography 
Services</A>, James Madison University</LI></UL>
<H2>Login</H2>";
#else
			RequestAccountDiv.Visible = false;
			AnnouncementDiv.Visible = false;
#endif
		}

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

		public override bool HasLeftMenu()
		{
			return false;
		}

		#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);
#if DEMO
#warning Compiling for Demo site
			this.CreateAccountButton.Click += new System.EventHandler(CreateAccountButton_Click);
#endif
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.GuestLoginButton.Click += new System.EventHandler(this.GuestLoginButton_Click);
			this.LoginButton.Click += new System.EventHandler(this.LoginButton_Click);
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion

		private void ProceedToAgreements()
		{
			string url;
			if (directlinkurl != null)
				url = String.Format("agreements.aspx?go={0}",
					Server.UrlEncode(directlinkurl));
			else
				url = "agreements.aspx";
			Response.Redirect(String.Format(
				"flashcheck.aspx?success={0}&maycontinue=yes&header=yes",
				Server.UrlEncode(url)));
		}

		private void LoginButton_Click(object sender, System.EventArgs e)
		{
			if (IsValid)
			{
				Orciid.Core.User user = Orciid.Core.User.GetByLogin(UsernameTextBox.Text, PasswordTextBox.Text);
				if (user != null && user.IsAuthenticated)
				{	
					SuccessfulLogin(user);
					if (directlinkresource != null)
						HandleDirectLinkToResource(directlinkid, directlinkresource);
					ProceedToAgreements();
				}
				else
				{
					TransactionLog.Instance.Add("Unsuccessful login attempt",
						String.Format("User: {0} ({1})\nLogin: {2}",
						Request.UserHostAddress,
						Request.UserHostName,
						UsernameTextBox.Text));
					ShowError(GetLocalString(this, "LoginFailed", "Invalid User name or Password. Please try again."));
				}
			}
		}

		private void SuccessfulLogin(Orciid.Core.User user)
		{
			TransactionLog.Instance.Add("Successful login",
				String.Format("User: {0} ({1})\nLogin: {2}",
				Request.UserHostAddress,
				Request.UserHostName,
				user.Login));
			Session["TempUser"] = user;
			user.Activate(Request.UserHostAddress);
			Properties props = Properties.GetProperties(user);
			if (props != null)
			{
				string xml = props.Get("lastsearch", null);
				if (xml != null)
					Session["LastSearch"] = xml;
			}			
		}

		private Orciid.Core.User CheckSingleSignOn()
		{
			string site = Request.QueryString["singlesignon"];
			if (site == null || site.Length == 0)
				return null;
			Hashtable parameters = new Hashtable();
			foreach (string key in Request.QueryString.Keys)
				if (!parameters.ContainsKey(key)) // skip multiple instances of same parameter
					parameters.Add(key, Request.QueryString[key]);
			Orciid.Core.User user = Orciid.Core.User.GetBySingleSignOn(site, parameters);
			if (user != null)
				SuccessfulLogin(user);
			else
				ShowError(GetLocalString(this, "SingleSignonFailed", 
					"Single sign-on failed, please log in manually or go back to the previous page"));
			return user;
		}

		private void GuestLoginButton_Click(object sender, System.EventArgs e)
		{
			Properties props = Properties.GetSystemProperties();
			if (props.GetAsInt("allowguest", 0) == 1)
			{
				Orciid.Core.User user = Orciid.Core.AnonymousUser.User;
				TransactionLog.Instance.Add("Successful login",
					String.Format("User: {0} ({1})\nLogin: {2}",
					Request.UserHostAddress,
					Request.UserHostName,
					"[guest login]"));
				Session["TempUser"] = user;
				ProceedToAgreements();
			}
		}

#if DEMO
#warning Compiling for Demo site

		private void CreateAccountButton_Click(object sender, System.EventArgs e)
		{
			string account = EmailAddressTextBox.Text;
			string firstname = FirstNameTextBox.Text;
			string lastname = LastNameTextBox.Text;
			if (account != null && account.Length > 0)
			{
				account = account.Trim();
				Orciid.Core.User user = Orciid.Core.User.GetByLogin(account);
				if (user != null)
				{
					AccountCreatedLabel.Text = "An account for this email address already exists.";
					AccountCreatedLabel.Visible = true;
				}
				else
				{
					string password = CreatePassword();
					if (firstname == null || firstname.Length == 0)
						firstname = "Demo";
					if (lastname == null || lastname.Length == 0)
						lastname = "User";
					try
					{
						DemoUserAuthentication.AddFullName(account, firstname, lastname);
						user = Orciid.Core.User.GetByLogin(account, password);
						SmtpMail.Send("mdid@jmu.edu", account, "Your MDID2 Demo Password",
							String.Format(@"
Thank you for requesting an account for the MDID2 Demo Web Site.

You can now log in at http://www.mdid.org/demo/ using this information:

User name: {0}
Password:  {1}

Please contact mdid@jmu.edu with questions and comments.", 
							account, password));
						UsernameTextBox.Text = account;
					}
					catch
					{
						AccountCreatedLabel.Text = "An error occurred while trying to send email. " +
							"Please make sure you specified a valid email address.";
					}
					AccountCreatedLabel.Visible = true;
				}
			}
		}

		private string CreatePassword()
		{
			string chars = "bdfghjkmnpqrstvwxyz23456789";
			string pwd = "";
			Random rnd = new Random();
			for (int i = 0; i < 6; i++)
				pwd += chars.Substring(rnd.Next() % chars.Length, 1);
			return pwd;
		}
#endif

		private void LanguageButton_Command(object sender, CommandEventArgs e)
		{
			if (e.CommandName == "language")
			{
				Session["Language"] = e.CommandArgument;
				LanguageChanged();
			}
		}
	}
}
