//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Web.UI.WebControls;
using CommunityServer.Components;
using CommunityServer.Reader.Components;
using CA = ComponentArt.Web.UI;

namespace CommunityServer.Reader.Controls
{
	public class Reader : FeedReaderTemplatedWebControl
	{
		CSContext csContext = CSContext.Current;

		#region Private Members

		private CA.TreeView tvFolderList;
		private CA.Menu rootMenu, folderMenu, feedMenu;

		private CA.CallBack ListingCallBack;
		private Repeater rPosts;
		private PlaceHolder PlaceHolder1;

		private CA.CallBack DisplayCallBack;
		private PlaceHolder phPostDisplay;
		private PlaceHolder phFolderSummary;
		private PlaceHolder phFeedSummary;
		private Literal lTitle;
		private Literal lAuthor;
		private Literal lDescription;
		private Literal lPubDate;
		private Literal lCommentsUrl;
		private Literal lLink;
		private Literal lFolderId;
		private Literal lFolderName;
		private Repeater rMostActiveArticles;
		private Repeater rMostRecentArticles;
		private Repeater rPostSummary;
		private Repeater rFeedsSummarized;

		#endregion

		#region Class Methods

		protected override void AttachChildControls()
		{
			tvFolderList			= (CA.TreeView) FindControl("tvFolderList");
			rootMenu				= (CA.Menu) FindControl("rootMenu");
			folderMenu				= (CA.Menu) FindControl("folderMenu");
			feedMenu				= (CA.Menu) FindControl("feedMenu");
			ListingCallBack			= (CA.CallBack) FindControl("ListingCallBack");
			rPosts					= (Repeater) FindControl("rPosts");
			PlaceHolder1			= (PlaceHolder) FindControl("PlaceHolder1");
			DisplayCallBack			= (CA.CallBack) FindControl("DisplayCallBack");
			phPostDisplay			= (PlaceHolder) FindControl("phPostDisplay");
			phFolderSummary			= (PlaceHolder) FindControl("phFolderSummary");
			phFeedSummary			= (PlaceHolder) FindControl("phFeedSummary");
			lTitle					= (Literal) FindControl("lTitle");
			lAuthor					= (Literal) FindControl("lAuthor");
			lDescription			= (Literal) FindControl("lDescription");
			lPubDate				= (Literal) FindControl("lPubDate");
			lCommentsUrl			= (Literal) FindControl("lCommentsUrl");
			lLink					= (Literal) FindControl("lLink");
			lFolderId				= (Literal) FindControl("lFolderId");
			lFolderName				= (Literal) FindControl("lFolderName");
			rMostActiveArticles		= (Repeater) FindControl("rMostActiveArticles");
			rMostRecentArticles 	= (Repeater) FindControl("rMostRecentArticles");
			rPostSummary			= (Repeater) FindControl("rPostSummary");
			rFeedsSummarized		= (Repeater) FindControl("rFeedsSummarized");

			tvFolderList.ClientSideOnNodeSelect = string.Format("new Function('node', 'return eval(\\'{0}.SelectTreeNode(node);\\');')", this.ClientID);
			tvFolderList.ClientSideOnNodeRename = string.Format("new Function('node', 'name', 'return eval(\\'{0}.RenameTreeNode(node, name);\\');')", this.ClientID);
			tvFolderList.ClientSideOnNodeMove = string.Format("new Function('sourceNode', 'targetNode', 'return eval(\\'{0}.MoveTreeNode(sourceNode, targetNode);\\');')", this.ClientID);
			tvFolderList.OnContextMenu =  string.Format("new Function('treeNode', 'e', 'return eval(\\'{0}.OpenContextMenu(treeNode, e);\\');')", this.ClientID);
			rootMenu.ClientSideOnItemSelect =  string.Format("new Function('menuItem', 'return eval(\\'{0}.ClickContextMenuItem(menuItem);\\');')", this.ClientID);
			folderMenu.ClientSideOnItemSelect =  string.Format("new Function('menuItem', 'return eval(\\'{0}.ClickContextMenuItem(menuItem);\\');')", this.ClientID);
			feedMenu.ClientSideOnItemSelect =  string.Format("new Function('menuItem', 'return eval(\\'{0}.ClickContextMenuItem(menuItem);\\');')", this.ClientID);

			DisplayCallBack.Callback 		+= new ComponentArt.Web.UI.CallBack.CallbackEventHandler(DisplayCallBack_Callback);
			ListingCallBack.Callback 		+= new ComponentArt.Web.UI.CallBack.CallbackEventHandler(GridCallBack_Callback);
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad (e);
			
			CSPage page = this.Page as CSPage;
			if(!Page.IsPostBack && !page.IsCallBack)
				DataBind();

			AjaxManager.Register(this,"ReaderAJAX");
		}


		public override void DataBind()
		{
			base.DataBind ();
			
			LoadBaseState();
		}

		protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender (e);

			Page.RegisterClientScriptBlock(this.GetType().FullName, string.Format("<script src=\"{0}\" language=\"javascript\"></script>", Page.Response.ApplyAppPathModifier("~/Utility/reader/feedreader.js")));
			Page.RegisterStartupScript(this.ClientID, 
				string.Format("<script language=\"javascript\">var {0} = new Reader('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}');</script>", 
					ClientID,
					tvFolderList.ClientID, 
					ListingCallBack.ClientID, 
					DisplayCallBack.ClientID, 
					DisplayCallBack.ClientID, 
					rootMenu.ClientID,
					folderMenu.ClientID,
					feedMenu.ClientID));
		}

		#endregion

		#region Private Methods

		private void LoadBaseState()
		{
			CA.TreeViewNode node = new CA.TreeViewNode();

			// Add in the root folder.
			node.Text				= FeedReaderResourceManager.GetString("reader_root_node_my_feeds");
			node.ID					= "folder-0-0";
			node.ContentCallbackUrl = Context.Response.ApplyAppPathModifier("~/reader/FolderXml.ashx?ParentFolderId=0");
			node.DraggingEnabled	= false;
			node.DroppingEnabled	= true;
			node.ImageUrl			= "images/inbox.gif";

			tvFolderList.Nodes.Add(node);

		}

		#endregion

		#region AJAX Methods

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public void RenameFolder(string folderNodeId, string newName)
		{
			string[] folderInputs = folderNodeId.Split('-');
			int folderId = 0;
			if (folderInputs.Length > 2)
				folderId = Convert.ToInt32(folderInputs[2]);
			
			if (folderId != 0 && newName != null)
				FeedReaderDataProvider.Instance().RenameFolder(folderId, newName);	
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public void DeleteFolder(string folderNodeId)
		{
			string[] folderInputs = folderNodeId.Split('-');
			int folderId = 0;

			if (folderInputs.Length > 2)
				folderId = Convert.ToInt32(folderInputs[2]);

			if (folderId != 0)
				FeedReaderDataProvider.Instance().DeleteFolder(folderId);
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public void DeleteFeed(string feedNodeId)
		{
			string[] feedInputs = feedNodeId.Split('-');
			int userId = csContext.User.UserID;
			int feedId = 0;

			if (feedInputs.Length > 1)
				feedId = Convert.ToInt32(feedInputs[1]);

            if (feedId != 0)
            {
                Feeds.DeleteFeed(userId,feedId);
            }
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public void MoveNode(string sourceNodeId, string targetNodeId)
		{
			string[] sourceInputs = sourceNodeId.Split('-');
			string[] targetInputs = targetNodeId.Split('-');
			string sourceType;
			int sourceId;
			int sourceFolderFeedId = 0;
			int targetId;

			sourceType = sourceInputs[0];
			sourceId = Convert.ToInt32(sourceType == "folder" ? sourceInputs[2] : sourceInputs[1]);
			targetId = Convert.ToInt32(targetInputs[2]);

			if (sourceType == "feed")
			{
				sourceFolderFeedId = Convert.ToInt32(sourceInputs[2]);

				FeedReaderDataProvider.Instance().MoveFeed(sourceFolderFeedId, targetId);
			}
			else
				FeedReaderDataProvider.Instance().MoveFolder(sourceId, targetId);
		}

		[AjaxMethod(IncludeControlValuesWithCallBack=false)]
		public void MarkPostRead(int feedId)
		{
			if(csContext.IsAuthenticated && feedId != 0)
				FeedReaderDataProvider.Instance().MarkPostRead(csContext.User.UserID, feedId);
		}

		#endregion

		#region Callback Handlers

		private void GridCallBack_Callback(object sender, CA.CallBackEventArgs e)
		{
			int userId = csContext.User.UserID;
			int feedId = 0;

			if (e.Parameter.ToLower().IndexOf("feed") >= 0)
			{
				string[] inputs = e.Parameter.Split('-');

				if (inputs.Length > 1)
					feedId = Convert.ToInt32(inputs[1]);
			}

			if (feedId != 0)
			{
				try
				{
					ArrayList feedPosts = FeedReaderDataProvider.Instance().GetFeedPosts(feedId, userId);
					
					rPosts.DataSource = feedPosts;
					rPosts.DataBind();

					PlaceHolder1.RenderControl(e.Output);
				}
				catch (Exception exc)
				{
					Console.Write(exc.Message);
				}
			}
		}

		private void DisplayCallBack_Callback(object sender, CA.CallBackEventArgs e)
		{
			if (e.Parameter.IndexOf("foldersummary") >= 0)
				FolderSummary_Render(e);
			else if (e.Parameter.IndexOf("feedsummary") >= 0)
				FeedSummary_Render(e);
			else
				PostDisplay_Render(e);
		}


		private void PostDisplay_Render(CA.CallBackEventArgs e)
		{
			string[] inputs = e.Parameter.Split('-');
			int feedPostId = 0;

			phFolderSummary.Visible = false;
			phFeedSummary.Visible = false;
			phPostDisplay.Visible = true;

			if (inputs.Length > 0)
				feedPostId = Convert.ToInt32(inputs[0]);

			if (feedPostId != 0)
			{
				FeedPost post = FeedReaderDataProvider.Instance().GetPost(feedPostId);

				lTitle.Text			= post.Title;
				lAuthor.Text		= post.Author;
				lDescription.Text	= ((IContent)post).RenderedBody(PostTarget.Web);
				lPubDate.Text		= post.PubDate.ToString();

				if (post.Creator != null && post.Creator != "")
					lPubDate.Text = lPubDate.Text + " by " + post.Creator;	

				if (post.CommentsUrl == null || post.CommentsUrl.Trim() == "")
					lCommentsUrl.Visible = false;
				else
				{
					if (post.CommentCount != int.MinValue && post.CommentCount >= 0)
						lCommentsUrl.Text = "<a href=\"" + post.CommentsUrl + "\" target=\"_blank\">" + post.CommentCount + " comment" + (post.CommentCount == 1 ? "" : "s") + "</a>";
					else
						lCommentsUrl.Text = "<a href=\"" + post.CommentsUrl + "\" target=\"_blank\">View comments</a>";	
				}
				
				lLink.Text = post.Link;
				phPostDisplay.RenderControl(e.Output);
			}
		}

		private void FolderSummary_Render(CA.CallBackEventArgs e)
		{
			int userId = csContext.User.UserID;
			int folderId = 0;
			string folderName = "";
			string[] inputs = e.Parameter.Split('-');

			phPostDisplay.Visible = false;
			phFeedSummary.Visible = false;
			phFolderSummary.Visible = true;
			
			if (inputs.Length > 1)
			{
				if (inputs.Length > 2)
					folderId = Convert.ToInt32(inputs[2]);

				if (inputs.Length > 3)
					folderName = inputs[3].ToString();
			}

			lFolderId.Text = folderId.ToString();
			lFolderName.Text = Globals.UrlEncode(folderName);
			
			ArrayList results = FeedReaderDataProvider.Instance().GetFolderSummary(userId, folderId);

			// Results is an ArrayList of three ArrayLists, containing three separate recordsets.
			// Let's work with the first recordset.
			ArrayList mostActiveResults = (ArrayList) results[0];

			rMostActiveArticles.DataSource = mostActiveResults;
			rMostActiveArticles.DataBind();

			// Next recordset.
			ArrayList mostRecentResults = (ArrayList) results[1];

			rMostRecentArticles.DataSource = mostRecentResults;
			rMostRecentArticles.DataBind();

			// Last recordset
			ArrayList postSummaryResults = (ArrayList) results[2];

			rPostSummary.DataSource = postSummaryResults;
			rPostSummary.DataBind();
		
			phFolderSummary.RenderControl(e.Output);
		}

		private void FeedSummary_Render(CA.CallBackEventArgs e)
		{
			int userId = csContext.User.UserID;
			int feedId = 0;
			string[] inputs = e.Parameter.Split('-');

			phPostDisplay.Visible = false;
			phFolderSummary.Visible = false;
			phFeedSummary.Visible = true;

			if (inputs.Length > 1)
				feedId = Convert.ToInt32(inputs[1]);

			ArrayList posts = FeedReaderDataProvider.Instance().GetFeedPosts(feedId, userId);

			rFeedsSummarized.DataSource = posts;
			rFeedsSummarized.DataBind();

			phFeedSummary.RenderControl(e.Output);			
		}

		#endregion
	}
}
