using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Bitrix.IBlock;
using System.Text;
using Bitrix.UI;

using System.Collections.Generic;
using Bitrix.Security;
using Bitrix.Modules;
using Bitrix;
using Bitrix.IO;
using Bitrix.Services.Text;
using Bitrix.DataLayer;

public partial class bitrix_admin_IBlockElementEdit : BXAdminPage
{
	protected int iblockId = -1;
	protected int typeId = -1;
	int elementId = -1;
	protected int redirectSectionId = 0;

	BXIBlockElement element;
    BXIBlock currentIBlock;

	bool currentUserCanModifyElement = false;

	string propertyEntryName;

	bool useVisualEditor = false;

	protected override string BackUrl
	{
		get
		{
			return base.BackUrl ?? string.Format("IBlockListAdmin.aspx?type_id={0}&iblock_id={1}&filter_sectionid={2}", typeId, iblockId, redirectSectionId);
		}
	}

    protected string GetSectionsName(){
        return BXHtmlTextEncoder.HtmlTextEncoder.Encode(currentIBlock.CaptionsInfo.SectionsName);
    }

	private void LoadData()
	{
		lbSections.Items.Clear();
		lbSections.Items.Add(new ListItem(GetMessageRaw("TopLevel"), "0"));
		foreach (BXIBlockSection sectionTmp in BXIBlockSection.GetTree(iblockId, 0, false, BXTextEncoder.EmptyTextEncoder))
		{
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < sectionTmp.DepthLevel; i++)
				sb.Append(" . ");
			sb.Append(sectionTmp.Name);
			lbSections.Items.Add(new ListItem(sb.ToString(), sectionTmp.Id.ToString()));
		}

		if (element == null)
		{
			if (redirectSectionId > 0)
				lbSections.SelectedValue = redirectSectionId.ToString();

			cbActive.Checked = true;
			tbSort.Text = "500";

			trID.Visible = false;
			trUpdateDate.Visible = false;
		}
		else
		{
			//Page.Title = string.Format(GetMessage("FormatPageTitle.ModificationOfElement"), elementId);
			//((BXAdminMasterPage)Page.Master).Title = Page.Title;

			trID.Visible = true;
			lbID.Text = element.Id.ToString();
			trUpdateDate.Visible = true;
			lbUpdateDate.Text = element.UpdateDate.ToString();

			cbActive.Checked = element.Active;
			tbCode.Text = element.Code;
			tbName.Text = element.Name;
			tbSort.Text = element.Sort.ToString();
			tbXmlId.Text = element.XmlId;
			tbTags.Text = element.Tags;

			PreviewImg.ImageFile = element.PreviewImage;
			DetailImg.ImageFile = element.DetailImage;

			if (useVisualEditor)
			{
				bxwePreviewText.Content = element.PreviewText;
				bxweDetailText.Content = element.DetailText;
				bxwePreviewText.StartMode = ((element.PreviewTextType == BXTextType.Text) ? BXWebEditor.StartModeType.PlainText : BXWebEditor.StartModeType.HTMLVisual);
				bxweDetailText.StartMode = ((element.DetailTextType == BXTextType.Text) ? BXWebEditor.StartModeType.PlainText : BXWebEditor.StartModeType.HTMLVisual);
			}
			else
			{
				tbPreviewText.Text = element.PreviewText;
				tbDetailText.Text = element.DetailText;
				rblPreviewTextType.SelectedValue = ((element.PreviewTextType == BXTextType.Text) ? "text" : "html");
				rblDetailTextType.SelectedValue = ((element.DetailTextType == BXTextType.Text) ? "text" : "html");
			}

			if (element.ActiveFromDate != DateTime.MinValue)
				tiActive.StartDate = element.ActiveFromDate;
			if (element.ActiveToDate != DateTime.MinValue)
				tiActive.EndDate = element.ActiveToDate;

			foreach (ListItem item in lbSections.Items)
			{
				int v;
				if (int.TryParse(item.Value, out v)
					&& element.Sections.Exists(CheckSection(v)))
					item.Selected = true;
			}
		}
	}

	Predicate<BXIBlockElement.BXInfoBlockElementSection> CheckSection(int value)
	{
		return delegate(BXIBlockElement.BXInfoBlockElementSection i) { return i.SectionId == value;	};
	}

	protected void Page_Init(object sender, EventArgs e)
	{
		useVisualEditor = BXIBlockModule.UseVisualEditor();

		elementId = base.GetRequestInt("id");
		hfElementId.Value = Request.Form[hfElementId.UniqueID];
        BXIBlock block = null;
		if (elementId > 0)
			hfElementId.Value = elementId.ToString();
		Int32.TryParse(hfElementId.Value, out elementId);
		if (elementId > 0)
		{
			element = BXIBlockElement.GetById(elementId, BXTextEncoder.EmptyTextEncoder);
			if (element == null)
			{
				elementId = 0;
				hfElementId.Value = elementId.ToString();
			}
		}

		if (elementId > 0)
		{
			iblockId = element.IBlockId;
			hfIBlockId.Value = iblockId.ToString();
			block = BXIBlock.GetById(iblockId, BXTextEncoder.EmptyTextEncoder);
			typeId = block.TypeId;
			hfTypeId.Value = typeId.ToString();
		}
		else
		{
			iblockId = base.GetRequestInt("iblock_id");
			if (iblockId > 0)
				hfIBlockId.Value = iblockId.ToString();
			Int32.TryParse(hfIBlockId.Value, out iblockId);
			block = null;
			if (iblockId > 0)
			{
				block = BXIBlock.GetById(iblockId, BXTextEncoder.EmptyTextEncoder);
				if (block == null)
				{
					iblockId = 0;
					hfIBlockId.Value = iblockId.ToString();
				}
			}

			if (iblockId > 0)
			{
				typeId = block.TypeId;
				hfTypeId.Value = typeId.ToString();
			}
			else
			{
				typeId = base.GetRequestInt("type_id");
				Response.Redirect(String.Format("IBlockAdmin.aspx?type_id={0}", typeId));
			}
		}
		propertyEntryName = String.Format("IBlock_{0}", iblockId);
        currentIBlock = block;
		int sectionId = base.GetRequestInt("section_id");
		if (sectionId > 0)
		{
			redirectSectionId = sectionId;
			if (elementId > 0)
			{
				if (element.Sections.Exists(CheckSection(sectionId)))
					redirectSectionId = sectionId;
				else
					if (element.Sections.Count > 0)
						redirectSectionId = element.Sections[0].SectionId;
					else
						redirectSectionId = 0;
			}
		}
		else
		{
			redirectSectionId = 0;
			if (elementId > 0)
			{
				if (element.Sections.Count > 0)
					redirectSectionId = element.Sections[0].SectionId;
				else
					redirectSectionId = 0;
			}
		}

		if (!this.BXUser.IsCanOperate("IBlockView", "iblock", iblockId))
			BXAuthentication.AuthenticationRequired();

		currentUserCanModifyElement = this.BXUser.IsCanOperate("IBlockModifyElements", "iblock", iblockId);

		bxwePreviewText.Visible = useVisualEditor;
		bxweDetailText.Visible = useVisualEditor;
		tbPreviewText.Visible = !useVisualEditor;
		rblPreviewTextType.Visible = !useVisualEditor;
		tbDetailText.Visible = !useVisualEditor;
		rblDetailTextType.Visible = !useVisualEditor;

		CustomFieldList1.EntityId = propertyEntryName;
		IBXCustomFieldList fl = CustomFieldList1 as IBXCustomFieldList;
		fl.Load(BXCustomEntityManager.GetProperties(propertyEntryName, elementId));
	}

	protected void Page_Load(object sender, EventArgs e)
	{
		string success = base.GetRequestString("success");
		if ("Y".Equals(success, StringComparison.InvariantCultureIgnoreCase))
			successMessage.Visible = true;
		else
			successMessage.Visible = false;

		if (!Page.IsPostBack)
			LoadData();

	}
	
	protected void Page_LoadComplete(object sender, EventArgs e)
	{
        string titleString = (elementId > 0)
        ? String.Format("{0} #{1}", currentIBlock.CaptionsInfo.ModifyingElement, elementId.ToString())
        : currentIBlock.CaptionsInfo.NewElement;
        Page.Title = BXHtmlTextEncoder.HtmlTextEncoder.Encode(titleString);
        ((BXAdminMasterPage)Page.Master).Title = Page.Title;
        GoToListButton.Text = BXHtmlTextEncoder.HtmlTextEncoder.Encode(currentIBlock.CaptionsInfo.ElementList);
        GoToListButton.Title = GoToListButton.Text;
		AddButton.Visible = (elementId > 0 && currentUserCanModifyElement);
		DeleteButton.Visible = (elementId > 0 && currentUserCanModifyElement);
		BXTabControl1.ShowApplyButton = BXTabControl1.ShowSaveButton = currentUserCanModifyElement;
        BXTabControlTab1.Text = currentIBlock.CaptionsInfo.ElementName;
        BXTabControlTab1.Title = titleString;
        BXTabControlTab4.Text = currentIBlock.CaptionsInfo.SectionsName;
        BXTabControlTab4.Title = BXTabControlTab4.Text;
        AddButton.Text = BXHtmlTextEncoder.HtmlTextEncoder.Encode(currentIBlock.CaptionsInfo.AddElement);
        DeleteButton.Text = BXHtmlTextEncoder.HtmlTextEncoder.Encode(currentIBlock.CaptionsInfo.DeleteElement);
        AddButton.Title = DeleteButton.Text;
        DeleteButton.Title = DeleteButton.Text;
	}

	protected void Page_PreRender(object sender, EventArgs e)
	{
		if (BXModuleManager.IsModuleInstalled("Search"))
		{
			BXPage.Scripts.RequireUtils();
			BXPage.RegisterScriptInclude("~/bitrix/js/Main/BXCompletionPopup.js");
			BXPage.RegisterScriptInclude("~/bitrix/js/Search/utils.js");
			ScriptManager.RegisterStartupScript(
				this, 
				GetType(), 
				"TagsCompletion", 
				string.Format(
                    "window.setTimeout(function(){{new Bitrix.Search.CompletionController(document.getElementById('{0}'), {{ siteId:'', moduleId:'iblock' }});}}, 0);", 
					tbTags.ClientID
				),
				true
			);
		}
	}

	protected void BXTabControl1_Command(object sender, BXTabControlCommandEventArgs e)
	{
		if (e.CommandName == "cancel" || (e.CommandName == "save" && SaveElement()))
			GoBack();	
		else if (e.CommandName == "apply" && SaveElement())
			Page.Response.Redirect(String.Format(
				"IBlockElementEdit.aspx?type_id={0}&iblock_id={1}&section_id={2}&id={3}&tabindex={4}", typeId, iblockId, GetElementSectionId(elementId), elementId, BXTabControl1.SelectedIndex));	
	}

	private int GetElementSectionId(int elementId)
	{
		int sectionId = 0;

		if (elementId > 0)
		{
			BXIBlockElement.BXInfoBlockElementSectionCollection sections = BXIBlockElement.BXInfoBlockElementSection.GetList(
				new BXFilter(
					new BXFilterItem(BXIBlockElement.BXInfoBlockElementSection.Fields.ElementId, BXSqlFilterOperators.Equal, elementId)
				),
				null
			);

			if (sections != null && sections.Count > 0)
				sectionId = sections[0].SectionId;
		}

		return sectionId;
	}

	private bool SaveElement()
	{
		if (Page.IsValid)
		{
			if (elementId > 0)
				return UpdateElement();
			else
				return CreateElement();
		}
		return false;
	}

	protected BXFile SaveFile(string type)
	{
		BXFile fImage = null;
		int imageId = -1;

		FileUpload fu;
		string tb;

		if ("detail".Equals(type, StringComparison.InvariantCultureIgnoreCase))
		{
			fu = DetailImg.Upload;
			tb = DetailImg.Description;
			if (element != null)
				imageId = element.DetailImageId;
		}
		else
		{
			fu = PreviewImg.Upload;
			tb = PreviewImg.Description;
			if (element != null)
				imageId = element.PreviewImageId;
		}

		if (fu.HasFile)
		{
			fImage = new BXFile(fu.PostedFile, "iblock", "iblock", tb);
			BXFileValidationResult fResult = fImage.ValidateAsImage(0, 0, 0);
			if (fResult != BXFileValidationResult.Valid)
			{
				string fError = "";
				if ((fResult & BXFileValidationResult.InvalidContentType) == BXFileValidationResult.InvalidContentType)
					fError += GetMessageRaw("InvalidType");
				if ((fResult & BXFileValidationResult.InvalidExtension) == BXFileValidationResult.InvalidExtension)
				{
					if (!String.IsNullOrEmpty(fError))
						fError += ", ";
					fError += GetMessageRaw("InvalidExtension");
				}
				if ((fResult & BXFileValidationResult.InvalidImage) == BXFileValidationResult.InvalidImage)
				{
					if (!String.IsNullOrEmpty(fError))
						fError += ", ";
					fError += GetMessageRaw("InvalidImage");
				}
				throw new Exception(String.Format(GetMessageRaw("Error.InvalidImage"), fError));
			}
			BXSecureIO.DemandUpload(fImage.FileVirtualPath);
			fImage.Save();
			return fImage;
		}
		else if (imageId > 0 && (fImage = BXFile.GetById(imageId)) != null)
		{
			fImage.Description = tb;
			fImage.Save();
		}

		return null;
	}

	private bool CreateElement()
	{
		try
		{
			if (!currentUserCanModifyElement)
				throw new Exception(GetMessageRaw("Exception.YouDontHaveRightsToCreateNewElement"));

			BXFile fPreviewImage = SaveFile("preview");
			BXFile fDetailImage = SaveFile("detail");

			int sort;
			int.TryParse(tbSort.Text, out sort);

			List<int> sections = new List<int>();
			foreach (ListItem item in lbSections.Items)
			{
				if (item.Selected)
				{
					int v;
					int.TryParse(item.Value, out v);
					if (v > 0)
						sections.Add(v);
				}
			}

			if (redirectSectionId < 0 || !sections.Contains(redirectSectionId))
			{
				if (sections.Count > 0)
					redirectSectionId = sections[0];
				else
					redirectSectionId = 0;
			}

			string prevText = null;
			string detText = null;
			BXTextType prevTextType = BXTextType.Text;
			BXTextType detTextType = BXTextType.Text;
			if (useVisualEditor)
			{
				prevText = bxwePreviewText.Content;
				prevTextType = (bxwePreviewText.StartMode == BXWebEditor.StartModeType.PlainText) ? BXTextType.Text : BXTextType.Html;
				detText = bxweDetailText.Content;
				detTextType = (bxweDetailText.StartMode == BXWebEditor.StartModeType.PlainText) ? BXTextType.Text : BXTextType.Html;
			}
			else
			{
				prevText = tbPreviewText.Text;
				prevTextType = ("text".Equals(rblPreviewTextType.SelectedValue, StringComparison.InvariantCultureIgnoreCase) ? BXTextType.Text : BXTextType.Html);
				detText = tbDetailText.Text;
				detTextType = ("text".Equals(rblDetailTextType.SelectedValue, StringComparison.InvariantCultureIgnoreCase) ? BXTextType.Text : BXTextType.Html);
			}

			try
			{
				element = new BXIBlockElement(iblockId, tbName.Text, BXTextEncoder.EmptyTextEncoder);
				element.CreatedBy = (this.BXUser.Identity as BXIdentity).Id;
				element.Active = cbActive.Checked;
				element.ActiveFromDate = tiActive.StartDate;
				element.ActiveToDate = tiActive.EndDate != DateTime.MaxValue ? tiActive.EndDate : DateTime.MinValue;
				element.Sort = (sort > 0 ? sort : 500);
				element.PreviewImageId = ((fPreviewImage != null) ? fPreviewImage.Id : 0);
				element.PreviewText = prevText;
				element.PreviewTextType = prevTextType;
				element.DetailImageId = ((fDetailImage != null) ? fDetailImage.Id : 0);
				element.DetailText = detText;
				element.DetailTextType = detTextType;
				element.XmlId = tbXmlId.Text;
				element.Code = tbCode.Text;
				element.Tags = tbTags.Text;

				foreach(int sectionId in sections)
					element.Sections.Add(sectionId);

				element.Save();
			}
			catch (Exception ex)
			{
				throw new Exception(GetMessageRaw("Exception.ElementCreationFailed"), ex);
			}

			//element = BXInfoBlockElementManagerOld.Create(
			//    (this.BXUser.Identity as BXIdentity).Id,
			//    iblockId,
			//    cbActive.Checked,
			//    tiActive.StartDate,
			//    tiActive.EndDate,
			//    (sort > 0 ? sort : 500),
			//    tbName.Text,
			//    ((fPreviewImage != null) ? fPreviewImage.Id : 0),
			//    prevText,
			//    prevTextType,
			//    ((fDetailImage != null) ? fDetailImage.Id : 0),
			//    detText,
			//    detTextType,
			//    tbXmlId.Text,
			//    tbCode.Text,
			//    sections.ToArray()
			//);
			//if (element == null)
			//    throw new Exception(GetMessageRaw("Exception.ElementCreationFailed"), ex);

			elementId = element.Id;
			hfElementId.Value = elementId.ToString();
			iblockId = element.IBlockId;
			hfIBlockId.Value = iblockId.ToString();

			BXCustomEntityManager.SaveEntity(propertyEntryName, element.Id, CustomFieldList1.Save());

			return true;
		}
		catch (BXEventException e)
		{
			foreach (string s in e.Messages)
				errorMassage.AddErrorMessage(s);
		}
		catch (Exception e)
		{
			errorMassage.AddErrorMessage(e.Message);
		}
		return false;
	}

	private bool UpdateElement()
	{
		try
		{
			if (!currentUserCanModifyElement)
				throw new Exception(GetMessageRaw("Exception.YouDontHaveRightsToModifyElement"));

			string prevText = null;
			string detText = null;
			BXTextType prevTextType = BXTextType.Text;
			BXTextType detTextType = BXTextType.Text;
			if (useVisualEditor)
			{
				prevText = bxwePreviewText.Content;
				detText = bxweDetailText.Content;
				prevTextType = (bxwePreviewText.StartMode == BXWebEditor.StartModeType.PlainText) ? BXTextType.Text : BXTextType.Html;
				detTextType = (bxweDetailText.StartMode == BXWebEditor.StartModeType.PlainText) ? BXTextType.Text : BXTextType.Html;
			}
			else
			{
				prevText = tbPreviewText.Text;
				detText = tbDetailText.Text;
				prevTextType = ("text".Equals(rblPreviewTextType.SelectedValue, StringComparison.InvariantCultureIgnoreCase) ? BXTextType.Text : BXTextType.Html);
				detTextType = ("text".Equals(rblDetailTextType.SelectedValue, StringComparison.InvariantCultureIgnoreCase) ? BXTextType.Text : BXTextType.Html);
			}

			element.Active = cbActive.Checked;
			element.ActiveFromDate = tiActive.StartDate;
			element.ActiveToDate = tiActive.EndDate != DateTime.MaxValue ? tiActive.EndDate : DateTime.MinValue;
			element.Code = tbCode.Text;
			element.DetailText = detText;
			element.DetailTextType = detTextType;
			element.PreviewText = prevText;
			element.PreviewTextType = prevTextType;
			element.ModifiedBy = (this.BXUser.Identity as BXIdentity).Id;
			element.Name = tbName.Text;
			element.XmlId = tbXmlId.Text;
			element.Tags = tbTags.Text;

			int sort;
			int.TryParse(tbSort.Text, out sort);
			element.Sort = sort;

			if (PreviewImg.DeleteFile)
				BXFile.Delete(element.PreviewImageId);
			BXFile fPreviewImage = SaveFile("preview");
			element.PreviewImageId = ((fPreviewImage != null) ? fPreviewImage.Id : (PreviewImg.DeleteFile ? 0 : element.PreviewImageId));

			if (DetailImg.DeleteFile)
				BXFile.Delete(element.DetailImageId);
			BXFile fDetailImage = SaveFile("detail");
			element.DetailImageId = ((fDetailImage != null) ? fDetailImage.Id : (DetailImg.DeleteFile ? 0 : element.DetailImageId));

			element.Sections.Clear();
			foreach (ListItem item in lbSections.Items)
			{
				if (item.Selected)
				{
					int v;
					int.TryParse(item.Value, out v);
					if (v > 0)
						element.Sections.Add(v);
				}
			}

			if (redirectSectionId < 0 || !element.Sections.Exists(CheckSection(redirectSectionId)))
			{
				if (element.Sections.Count > 0)
					redirectSectionId = element.Sections[0].SectionId;
				else
					redirectSectionId = 0;
			}

			element.Update();

			BXCustomEntityManager.SaveEntity(propertyEntryName, element.Id, CustomFieldList1.Save());

			return true;
		}
		catch (BXEventException e)
		{
			foreach (string s in e.Messages)
				errorMassage.AddErrorMessage(s);
		}
		catch (Exception e)
		{
			errorMassage.AddErrorMessage(e.Message);
		}

		return false;
	}

	protected void BXContextMenuToolbar1_CommandClick(object sender, CommandEventArgs e)
	{
		switch (e.CommandName)
		{
			case "DeleteElement":
				try
				{
					if (!currentUserCanModifyElement)
						throw new Exception(GetMessageRaw("Exception.YouDontHaveRightsToDeleteThisRecord"));

					if (elementId > 0)
					{
						if (redirectSectionId < 0 || !element.Sections.Exists(CheckSection(redirectSectionId)))
						{
							if (element.Sections.Count > 0)
								redirectSectionId = element.Sections[0].SectionId;
							else
								redirectSectionId = 0;
						}

						try
						{
							BXIBlockElement.Delete(elementId);
						}
						catch(Exception ex)
						{
							throw new Exception(GetMessageRaw("Exception.AnErrorHasOccurredWhileDeletingElement"), ex);
						}
					}
					else
					{
						throw new Exception(GetMessageRaw("Exception.ElementIsNotFound"));
					}

					Page.Response.Redirect(String.Format("IBlockListAdmin.aspx?type_id={0}&iblock_id={1}&filter_sectionid={2}", typeId, iblockId, redirectSectionId));
				}
				catch (BXEventException ex)
				{
					foreach (string s in ex.Messages)
						errorMassage.AddErrorMessage(s);
				}
				catch (Exception ex)
				{
					errorMassage.AddErrorMessage(ex.Message);
				}

				break;
		}
	}
}
