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.UI;
using Bitrix.Components;
using Bitrix.IBlock;
using Bitrix.DataLayer;
using System.Collections.Generic;
using Bitrix.Services;
using Bitrix;
using Bitrix.Configuration;
using Bitrix.IO;
using Bitrix.DataTypes;
using System.Text;
using Bitrix.Services.Text;
using Bitrix.Security;
using System.IO;
using Bitrix.UI.Popup;

namespace Bitrix.IBlock.Components
{
	public partial class CatalogueElementListComponent : BXComponent
	{
		#region Iblock properties

		public int IBlockId
		{
			get { return Parameters.Get<int>("IBlockId"); }
		}

		protected BXIBlock iblock;
		public BXIBlock IBlock
		{
			get { return iblock; }
			protected set { iblock = value; }
		}

		public string IBlockName
		{
			get { return ComponentCache.Get<string>("IBlockName", String.Empty); }
			set { ComponentCache["IBlockName"] = value; }
		}

		public string IBlockElementName
		{
			get { return ComponentCache.Get<string>("IBlockElementName", String.Empty); }
			set { ComponentCache["IBlockElementName"] = value; }
		}

		public string IBlockSectionName
		{
			get { return ComponentCache.Get<string>("IBlockSectionName", String.Empty); }
			set { ComponentCache["IBlockSectionName"] = value; }
		}

		public int IBlockTypeId
		{
			get { return ComponentCache.Get<int>("IBlockTypeId"); }
			set { ComponentCache["IBlockTypeId"] = value; }
		}

		#endregion

		#region Section properties

		protected BXIBlockSection section;
		public BXIBlockSection Section
		{
			get { return section; }
			set { section = value; }
		}

		private int sectionId = 0;
		public int SectionId
		{
			get
			{
				if (sectionId > 0)
					return sectionId;
				else
					return Parameters.Get<int>("SectionId");
			}
			private set { sectionId = value; }
		}

		public string SectionCode
		{
			get { return Parameters.Get<string>("SectionCode", String.Empty); }
		}

		public string SectionName
		{
			get
			{
				if (ComponentCache.ContainsKey("SectionName"))
					return ComponentCache.Get<string>("SectionName");
				return null;
			}
			set { ComponentCache["SectionName"] = value; }
		}

		#endregion

		protected List<ElementListItem> listItems;
		public List<ElementListItem> Items
		{
			get { return listItems; }
		}

		public List<string> ShowProperties
		{
			get { return Parameters.GetListString("Properties"); }
		}

		public bool isErrorOccured = false;
		public string errorMessage = String.Empty;

		protected void Page_Load(object sender, EventArgs e)
		{
			BXPagingParams pagingParams = PreparePagingParams();

			if (IsCached(((BXPrincipal)Page.User).GetAllRoles(true), pagingParams))
			{
				SetTemplateCachedData();
				return;
			}

			BXIBlockCollection iblockCollection = BXIBlock.GetList(
				new BXFilter(
					new BXFilterItem(BXIBlock.Fields.Active, BXSqlFilterOperators.Equal, "Y"),
					new BXFilterItem(BXIBlock.Fields.CheckPermissions, BXSqlFilterOperators.Equal, "Y"),
					new BXFilterItem(BXIBlock.Fields.ID, BXSqlFilterOperators.Equal, IBlockId)
				),
				null,
				null,
				null,
				BXTextEncoder.HtmlTextEncoder
			);

			if (iblockCollection == null || iblockCollection.Count < 1)
			{
				GenerateNotFoundError(GetMessage("WrongIBlockCode"));
				return;
			}

			IBlockTypeId = iblockCollection[0].TypeId;
			IBlock = iblockCollection[0];
			IBlockName = iblockCollection[0].Name;
			IBlockElementName = iblockCollection[0].ElementName;
			IBlockSectionName = iblockCollection[0].SectionName;

			Dictionary<string, BXCustomField> iblockCustomFields = new Dictionary<string, BXCustomField>(iblock.CustomFields.Count);
			foreach (BXCustomField field in iblock.CustomFields)
				iblockCustomFields[field.CorrectedName] = field;

			//Filter
			if (!String.IsNullOrEmpty(SectionCode))
			{
				#region old
				//String[] sectionCodeChain = SectionCode.Trim('/').Split('/');
				//int? parentSectionID = null;
				//for (int i = 0; i < sectionCodeChain.Length; i++)
				//{
				//    BXIBlockSectionCollection sectionCollection = BXIBlockSection.GetList(
				//        new BXFilter(
				//            new BXFilterItem(BXIBlockSection.Fields.Code, BXSqlFilterOperators.Equal, sectionCodeChain[i]),
				//            new BXFilterItem(BXIBlockSection.Fields.Active, BXSqlFilterOperators.Equal, "Y"),
				//            new BXFilterItem(BXIBlockSection.Fields.SectionId, BXSqlFilterOperators.Equal, parentSectionID)
				//        ),
				//        null
				//    );

				//    if (sectionCollection == null || sectionCollection.Count < 1)
				//    {
				//        Section = null;
				//        GenerateNotFoundError(GetMessage("SectionNotFound"));
				//        return;
				//    }

				//    Section = sectionCollection[0];
				//    SectionId = sectionCollection[0].Id;
				//    parentSectionID = sectionCollection[0].Id;
				//}
				#endregion
				BXFilter sectionFilter = new BXFilter(
					new BXFilterItem(BXIBlockSection.Fields.IBlock.ID, BXSqlFilterOperators.Equal, IBlockId),
					new BXFilterItem(BXIBlockSection.Fields.ActiveGlobal, BXSqlFilterOperators.Equal, "Y"),
					new BXFilterItem(BXIBlockSection.Fields.Code, BXSqlFilterOperators.Equal, SectionCode)
				);

				if (SectionId > 0)
					sectionFilter.Add(new BXFilterItem(BXIBlockSection.Fields.ID, BXSqlFilterOperators.Equal, SectionId));

				BXIBlockSectionCollection section = BXIBlockSection.GetList(sectionFilter, null, null, null, BXTextEncoder.HtmlTextEncoder);
				if (section != null && section.Count > 0)
				{
					Section = section[0];
					SectionId = section[0].Id;
				}
				else
				{
					Section = null;
					GenerateNotFoundError(GetMessage("SectionNotFound"));
					return;
				}
			}
			else if (SectionId > 0)
			{
				BXIBlockSectionCollection sectionCollection = BXIBlockSection.GetList(
					new BXFilter(
						new BXFilterItem(BXIBlockSection.Fields.IBlock.ID, BXSqlFilterOperators.Equal, IBlockId),
						new BXFilterItem(BXIBlockSection.Fields.ID, BXSqlFilterOperators.Equal, SectionId),
						new BXFilterItem(BXIBlockSection.Fields.ActiveGlobal, BXSqlFilterOperators.Equal, "Y")
					),
					null,
					null,
					null,
					BXTextEncoder.HtmlTextEncoder
				);

				if (sectionCollection == null || sectionCollection.Count < 1)
				{
					GenerateNotFoundError(GetMessage("SectionNotFound"));
					return;
				}

				Section = sectionCollection[0];
			}

			BXParamsBag<object> pagingReplace = new BXParamsBag<object>();
			pagingReplace["IblockId"] = IBlock.Id;
			pagingReplace["IblockCode"] = IBlock.Code;
			if (Section != null && SectionId > 0)
			{
				SectionName = Section.Name;

				pagingReplace["SectionCode"] = Section.Code;
				pagingReplace["SECTION_CODE"] = Section.Code;
				pagingReplace["SectionId"] = Section.Id;
				pagingReplace["SECTION_ID"] = Section.Id;
			}


			BXFilter elementFilter = new BXFilter(
				new BXFilterItem(BXIBlockElement.Fields.Active, BXSqlFilterOperators.Equal, "Y"),
				new BXFilterItem(BXIBlockElement.Fields.IBlock.ID, BXSqlFilterOperators.Equal, IBlockId),
				new BXFilterItem(BXIBlockElement.Fields.CheckPermissions, BXSqlFilterOperators.Equal, "Y")
			);

			if (SectionId > 0)
			{
				elementFilter.Add(new BXFilterItem(BXIBlockElement.Fields.Sections.Section.ID, BXSqlFilterOperators.Equal, SectionId));

				if (Parameters.Get<bool>("ShowSubElements", true))
					elementFilter.Add(new BXFilterItem(BXIBlockElement.Fields.IncludeParentSections, BXSqlFilterOperators.Equal, "Y"));
			}
			else if (!Parameters.Get<bool>("ShowAllElementsOnIndex", true))
			{
				elementFilter.Add(new BXFilterItem(BXIBlockElement.Fields.InRootSection, BXSqlFilterOperators.Equal, true));
			}

			//Sorting
			BXOrderBy elementOrderBy = new BXOrderBy();
			string sortBy = Parameters.Get<string>("SortBy", "Id");
			string sortOrder = Parameters.Get<string>("SortOrder", "Desc");

			if (sortBy.StartsWith("-", StringComparison.OrdinalIgnoreCase))
			{
				sortBy = sortBy.Substring(1).ToUpper();
				if (iblockCustomFields.ContainsKey(sortBy))
					elementOrderBy.Add(BXIBlockElement.Fields.GetCustomField(IBlockId, sortBy), sortOrder);
			}
			else
				elementOrderBy.Add(BXIBlockElement.Fields, sortBy, sortOrder);

			//Paging
			bool isLegalPage;
			BXQueryParams queryParams = PreparePaging(
				pagingParams,
				delegate { return BXIBlockElement.Count(elementFilter); },
				pagingReplace,
				out isLegalPage
			);

			if (!Parameters.Get<bool>("PagingAllow"))
				queryParams = new BXQueryParams(new BXPagingOptions(0, Parameters.Get<int>("PagingRecordsPerPage", 10)));
			else if (!isLegalPage)
				AbortCache();

			BXIBlockElementCollection iblockElements = BXIBlockElement.GetList(
				elementFilter,
				elementOrderBy,
				new BXSelectAdd(BXIBlockElement.Fields.Sections.Section),
				queryParams,
				BXTextEncoder.HtmlTextEncoder
			);

			listItems = new List<ElementListItem>();

			foreach (BXIBlockElement iblockElement in iblockElements)
			{
				ElementListItem listItem = new ElementListItem();

				listItem.Element = iblockElement;

				string url = Parameters.Get<string>("ElementDetailUrl");
				if (!String.IsNullOrEmpty(url))
				{
					int replaceSectionId = 0;
					string replaceSectionCode = String.Empty;
					
					// Hellish logic to get the section for the element
					BXIBlockSectionCollection sections = iblockElement.GetSections();
					if (sections != null && sections.Count != 0)
					{
						bool hasSectionCode = !string.IsNullOrEmpty(SectionCode);
						if (SectionId != 0 || hasSectionCode)
						{
							foreach (BXIBlockSection s in sections)
							{
								if (!s.ActiveGlobal)
									continue;
								if (SectionId == s.Id || hasSectionCode && SectionCode == s.TextEncoder.Decode(s.Code))
								{
									replaceSectionId = s.Id;
									replaceSectionCode = s.Code;
									break;
								}
							}
						}
						if (replaceSectionId == 0)
						{
							foreach (BXIBlockSection s in sections)
							{
								if (!s.ActiveGlobal)
									continue;
								replaceSectionId = s.Id;
								replaceSectionCode = s.Code;
								break;
							}
						}
					}

					BXParamsBag<object> replaceItems = new BXParamsBag<object>();
					replaceItems.Add("IblockId", iblockElement.IBlockId);
					replaceItems.Add("IBLOCK_ID", iblockElement.IBlockId);
					replaceItems.Add("IblockCode", IBlock.Code);
					replaceItems.Add("IBLOCK_CODE", IBlock.Code);
					replaceItems.Add("ELEMENT_ID", iblockElement.Id);
					replaceItems.Add("ElementId", iblockElement.Id);
					replaceItems.Add("ElementCode", iblockElement.Code);
					replaceItems.Add("ELEMENT_CODE", iblockElement.Code);
					replaceItems.Add("SectionId", replaceSectionId);
					replaceItems.Add("SECTION_ID", replaceSectionId);
					replaceItems.Add("SectionCode", replaceSectionCode);
					replaceItems.Add("SECTION_CODE", replaceSectionCode);

					url = BXSefUrlUtility.MakeLink(url, replaceItems);
					//url = MakeLink(url, replaceItems);

					listItem.ElementDetailUrl = url;
				}

				List<ElementListItemProperty> elementProperties = new List<ElementListItemProperty>();
				foreach (KeyValuePair<string, BXCustomProperty> elementProperty in iblockElement.Properties)
				{
					ElementListItemProperty property = new ElementListItemProperty();
					property.Name = elementProperty.Value.UserLikeName;
					property.Property = elementProperty.Value;

					string correctedName = elementProperty.Value.Name.ToUpper();
					property.Code = correctedName;
					if (iblockCustomFields.ContainsKey(correctedName))
						property.Field = iblockCustomFields[correctedName];

					property.Values = elementProperty.Value.Values;
					property.DisplayValue = GetCustomProperty(property.Property, property.Field, "&nbsp;/&nbsp;");
					elementProperties.Add(property);
				}

				listItem.Properties = elementProperties;
				listItems.Add(listItem);
			}

			SetTemplateCachedData();
			IncludeComponentTemplate();
		}

		private void SetTemplateCachedData()
		{
			BXPublicPage bitrixPage = Page as BXPublicPage;
			if (bitrixPage != null && !IsComponentDesignMode)
			{
				if (Parameters.Get<bool>("SetPageTitle", true) && SectionName != null)
					bitrixPage.BXTitle = BXTextEncoder.HtmlTextEncoder.Decode(SectionName);
			}
		}

		private void GenerateNotFoundError(string error)
		{
			isErrorOccured = true;
			errorMessage = error;

			AbortCache();

			ScriptManager ajax = ScriptManager.GetCurrent(Page);
			if (!IsComponentDesignMode && BXConfigurationUtility.ShowMode == BXShowMode.View && (ajax == null || !ajax.IsInAsyncPostBack))
			{
				BXError404Manager.Set404Status(Response);

				BXPublicPage bitrixPage = Page as BXPublicPage;
				if (bitrixPage != null && Parameters.GetBool("SetPageTitle", true) && !String.IsNullOrEmpty(error))
					bitrixPage.Title = error;
			}

			IncludeComponentTemplate();
		}

		private string GetCustomProperty(BXCustomProperty property, BXCustomField field, string separator)
		{
			BXCustomTypePublicView view = BXCustomTypeManager.GetCustomType(field.CustomTypeId).CreatePublicView();
			view.Init(property, field);
			return view.GetHtml(separator);
		}

		#region Admin Panel & Context Menu

		public string AdminPanelSectionId
		{
			get { return "CatalogueListMenuSection"; }
		}

		public string AdminPanelButtonMenuId
		{
			get { return String.Format("CatalogueListButtonMenu_{0}", IBlockId); }
		}

		//Создаем секцию и кнопку для выпадающего меню в панели администратора
		public override void CreatePublicPanelMenu(BXPublicPanelMenuSectionList sectionList)
		{
			if (!Parameters.Get<bool>("AddAdminPanelButtons") || isErrorOccured)
				return;

			if (sectionList == null)
				throw new ArgumentNullException("sectionList");

			if (!BXIBlock.IsUserCanOperate(IBlockId, BXIBlock.Operations.IBlockAdminRead) ||
				!BXIBlock.IsUserCanOperate(IBlockId, BXIBlock.Operations.IBlockModifyElements))
				return;

			//Создаем секцию
			BXPublicPanelMenuSection iblockListSection = sectionList.FindByID(AdminPanelSectionId);
			if (iblockListSection == null)
			{
				BXPublicPanelMenuSectionInfo sectionInfo = new BXPublicPanelMenuSectionInfo(AdminPanelSectionId, 100);
				iblockListSection = new BXPublicPanelMenuSection(sectionInfo);
				sectionList.Add(iblockListSection);
			}

			//Создаем кнопку
			BXPublicPanelMenu listButtonMenu = iblockListSection.FindByID(AdminPanelButtonMenuId);
			if (listButtonMenu == null)
			{
				listButtonMenu = new BXPublicPanelMenu();
				listButtonMenu.ID = AdminPanelButtonMenuId;
				listButtonMenu.BackgroundImagePath = BXPath.Combine(BXComponentManager.GetFolder(Name), "/images/iblock.gif");
				listButtonMenu.Caption = BXTextEncoder.HtmlTextEncoder.Decode(IBlockName);
				listButtonMenu.Hint = BXTextEncoder.HtmlTextEncoder.Decode(IBlockName);
				listButtonMenu.ShowMode = BXShowMode.NonView;
				iblockListSection.Add(listButtonMenu);
			}
		}

		//Заполняем выпадающее меню пунктами
		public override void PopulatePublicPanelMenu(BXPublicPanelMenuSectionList sectionList)
		{
			if (!Parameters.Get<bool>("AddAdminPanelButtons") || isErrorOccured)
				return;

			if (sectionList == null)
				throw new ArgumentNullException("sectionList");

			if (!BXIBlock.IsUserCanOperate(IBlockId, BXIBlock.Operations.IBlockAdminRead) ||
				!BXIBlock.IsUserCanOperate(IBlockId, BXIBlock.Operations.IBlockModifyElements))
				return;

			BXPublicPanelMenuSection iblockListSection = sectionList.FindByID(AdminPanelSectionId);
			if (iblockListSection == null)
				return;

			BXPublicPanelMenu listButtonMenu = iblockListSection.FindByID(AdminPanelButtonMenuId);
			if (listButtonMenu == null)
				return;

			if (listButtonMenu.PopupMenu == null)
				listButtonMenu.PopupMenu = new BXPopupMenuV2();

			BXPopupMenuItem[] menuItems = GetMenuItems();
			for (int menuIndex = 0; menuIndex < menuItems.Length; menuIndex++)
			{
				bool itemExists = false;
				foreach (BXPopupMenuBaseItem item in listButtonMenu.PopupMenu.Items)
				{
					if (item.ID == menuItems[menuIndex].ID)
					{
						itemExists = true;
						break;
					}
				}

				if (!itemExists)
					listButtonMenu.PopupMenu.AddItem(menuItems[menuIndex]);
			}
		}

		public BXPopupMenuItem[] GetMenuItems()
		{
			BXPopupMenuItem[] menuItems = new BXPopupMenuItem[2];

			menuItems[0] = new BXPopupMenuItem();
			menuItems[0].BackgroundImagePath = BXPath.Combine(BXComponentManager.GetFolder(Name), "/images/new_element.gif");
			menuItems[0].ID = String.Format("catalogue_element_new_{0}", IBlockId);
			menuItems[0].Text = (iblock != null) ? BXHtmlTextEncoder.HtmlTextEncoder.Decode(iblock.CaptionsInfo.AddElement) :
				String.Format(GetMessageRaw("AddNewElement"), String.IsNullOrEmpty(IBlockElementName) ? GetMessageRaw("IBlockElementName") : BXTextEncoder.HtmlTextEncoder.Decode(IBlockElementName.ToLower()));
			menuItems[0].ClientClickScript =
				String.Format(
					"jsUtils.Redirect(arguments, '{0}?type_id={2}&iblock_id={1}&section_id={3}&{4}={5}')",
					VirtualPathUtility.ToAbsolute("~/bitrix/admin/IBlockElementEdit.aspx"),
					IBlockId,
					IBlockTypeId,
					SectionId,
					BXConfigurationUtility.Constants.BackUrl,
					UrlEncode(BXSefUrlManager.CurrentUrl.PathAndQuery)
				);

			menuItems[1] = new BXPopupMenuItem();
			menuItems[1].BackgroundImagePath = BXPath.Combine(BXComponentManager.GetFolder(Name), "/images/new_section.gif");
			menuItems[1].ID = String.Format("catalogue_element_section_new_{0}", IBlockId);
			menuItems[1].Text = (iblock != null) ? BXHtmlTextEncoder.HtmlTextEncoder.Decode(iblock.CaptionsInfo.AddSection) :
				String.Format(GetMessageRaw("AddNewSection"), String.IsNullOrEmpty(IBlockSectionName) ? GetMessageRaw("IBlockSectionName") : BXTextEncoder.HtmlTextEncoder.Decode(IBlockSectionName.ToLower()));
			menuItems[1].ClientClickScript =
				String.Format(
					"jsUtils.Redirect(arguments, '{0}?type_id={2}&iblock_id={1}&section_id={3}&{4}={5}')",
					VirtualPathUtility.ToAbsolute("~/bitrix/admin/IBlockSectionEdit.aspx"),
					IBlockId,
					IBlockTypeId,
					SectionId,
					BXConfigurationUtility.Constants.BackUrl,
					UrlEncode(BXSefUrlManager.CurrentUrl.PathAndQuery)
				);

			return menuItems;
		}

		//Создаем контекстное меню
		public override BXComponentPopupMenuInfo PopupMenuInfo
		{
			get
			{
				BXComponentPopupMenuInfo info = base.PopupMenuInfo;

				if (BXIBlock.IsUserCanOperate(IBlockId, BXIBlock.Operations.IBlockAdminRead) &&
					BXIBlock.IsUserCanOperate(IBlockId, BXIBlock.Operations.IBlockModifyElements) && !isErrorOccured)
				{
					info.CreateCustomPopupMenuItems = delegate(BXShowMode showMode)
					{
						if (showMode != BXShowMode.View)
							return GetMenuItems();
						else
							return null;
					};
				}
				return info;
			}
		}

		#endregion


		protected override void PreLoadComponentDefinition()
		{
			Title = GetMessageRaw("Title");
			Description = GetMessageRaw("Description");
			Icon = "images/cat_list.gif";
			Group = new BXComponentGroup("catalogue", GetMessageRaw("Group"), 100, BXComponentGroup.Content);

			BXCategory dataSourceCategory = BXCategory.DataSource;
			BXCategory mainCategory = BXCategory.Main;
			BXCategory addSettingsCategory = BXCategory.AdditionalSettings;
			BXCategory sefCategory = BXCategory.Sef;

			ParamsDefinition.Add(BXParametersDefinition.Cache);
			ParamsDefinition.Add(BXParametersDefinition.Paging);
			ParamsDefinition.Add(BXParametersDefinition.PagingUrl);

			ParamsDefinition.Add(
				"IBlockTypeId",
				new BXParamSingleSelection(
					GetMessageRaw("InfoBlockType"),
					String.Empty,
					mainCategory
				)
			);

			ParamsDefinition.Add(
				"IBlockId",
				new BXParamSingleSelection(
					GetMessageRaw("InfoBlockCode"),
					String.Empty,
					mainCategory
				)
			);

			ParamsDefinition.Add(
				"SectionId",
				new BXParamText(
					GetMessageRaw("SectionID"),
					"0",
					mainCategory
				));

			ParamsDefinition.Add(
				"SectionCode",
				new BXParamText(
				GetMessageRaw("SectionMnemonicCode"),
				"",
				mainCategory
			));

			ParamsDefinition.Add(
				"SortBy",
				new BXParamSingleSelection(
					GetMessageRaw("SortBy"),
					"Id",
					dataSourceCategory
				)
			);

			ParamsDefinition.Add(
				"SortOrder",
				new BXParamSort(
					GetMessageRaw("SortOrder"),
					true,
					dataSourceCategory
				)
			);

			ParamsDefinition.Add(
				"ShowSubElements",
				new BXParamYesNo(
					GetMessageRaw("DisplaySubsectionElements"),
					true,
					dataSourceCategory
				));

			ParamsDefinition.Add(
				"ShowAllElementsOnIndex",
				new BXParamYesNo(
					GetMessageRaw("ShowAllElementsOnIndex"),
					true,
					dataSourceCategory

			));

			ParamsDefinition.Add(
				"Properties",
				new BXParamMultiSelection(
					GetMessageRaw("Properties"),
					"-",
					addSettingsCategory
				));

			ParamsDefinition.Add(
				"AddAdminPanelButtons",
				new BXParamYesNo(
					GetMessageRaw("AddButtonsForThisComponentToAdminPanel"),
					false,
					addSettingsCategory
				));

			ParamsDefinition.Add(
				"SetPageTitle",
				new BXParamYesNo(
					GetMessageRaw("SetPageTitle"),
					true,
					addSettingsCategory
				));

			ParamsDefinition.Add(
				"SectionElementListUrl",
				new BXParamText(
					GetMessageRaw("Section"),
					"list.aspx?section_id=#SECTION_ID#",
					sefCategory
				));

			ParamsDefinition.Add(
				"ElementDetailUrl",
				new BXParamText(
					GetMessageRaw("DetailedInfo"),
					"detail.aspx?section_id=#SECTION_ID#&element_id=#ELEMENT_ID#",
					sefCategory
				));
		}

		protected override void LoadComponentDefinition()
		{
			//Iblock type
			List<BXParamValue> typeParamValue = new List<BXParamValue>();
			typeParamValue.Add(new BXParamValue(GetMessageRaw("SelectIBlockType"), ""));

			BXIBlockTypeCollection iblockTypes = BXIBlockType.GetList(null, new BXOrderBy(new BXOrderByPair(BXIBlockType.Fields.Name, BXOrderByDirection.Asc)), null, null, BXTextEncoder.EmptyTextEncoder);
			foreach (BXIBlockType iblockType in iblockTypes)
				typeParamValue.Add(new BXParamValue(iblockType.Translations[BXLoc.CurrentLocale].Name, iblockType.Id.ToString()));

			ParamsDefinition["IBlockTypeId"].Values = typeParamValue;
			ParamsDefinition["IBlockTypeId"].RefreshOnDirty = true;

			//Iblock
			int selectedIBlockType = 0;
			if (Parameters.ContainsKey("IBlockTypeId"))
				int.TryParse(Parameters["IBlockTypeId"], out selectedIBlockType);

			BXFilter filter = new BXFilter();
			if (selectedIBlockType > 0)
				filter.Add(new BXFilterItem(BXIBlock.Fields.Type.ID, BXSqlFilterOperators.Equal, selectedIBlockType));
			if (!String.IsNullOrEmpty(DesignerSite))
				filter.Add(new BXFilterItem(BXIBlock.Fields.Sites.SiteId, BXSqlFilterOperators.Equal, DesignerSite));

			List<BXParamValue> iblockParamValue = new List<BXParamValue>();
			iblockParamValue.Add(new BXParamValue(GetMessageRaw("SelectIBlockID"), "-"));
			BXIBlockCollection iblocks = BXIBlock.GetList(filter, new BXOrderBy(new BXOrderByPair(BXIBlock.Fields.Name, BXOrderByDirection.Asc)), null, null, BXTextEncoder.EmptyTextEncoder);
			foreach (BXIBlock iblock in iblocks)
				iblockParamValue.Add(new BXParamValue(iblock.Name, iblock.Id.ToString()));

			ParamsDefinition["IBlockId"].Values = iblockParamValue;
			ParamsDefinition["IBlockId"].RefreshOnDirty = true;

			//Properties
			List<BXParamValue> iblockProperty = new List<BXParamValue>();
			int selectedIblockId = 0;
			if (Parameters.ContainsKey("IBlockId"))
				int.TryParse(Parameters["IBlockId"], out selectedIblockId);

			List<BXParamValue> properties = new List<BXParamValue>();
			List<BXParamValue> sortProperties = new List<BXParamValue>();

			properties.Add(new BXParamValue(GetMessageRaw("NotSelected"), "-"));
			if (selectedIblockId > 0)
			{
				BXCustomFieldCollection customFields = BXIBlock.GetCustomFields(selectedIblockId);
				foreach (BXCustomField customField in customFields)
				{
					string title = BXTextEncoder.HtmlTextEncoder.Decode(customField.EditFormLabel);
					string code = customField.Name.ToUpper();
					properties.Add(new BXParamValue(title, code));
					sortProperties.Add(new BXParamValue(title, "-" + code));
				}
			}

			ParamsDefinition["Properties"].Values = properties;

			//Sorting
			List<BXParamValue> sortingFields = new List<BXParamValue>();
			sortingFields.Add(new BXParamValue(GetMessageRaw("ElementID"), "ID"));
			sortingFields.Add(new BXParamValue(GetMessageRaw("ElementName"), "Name"));
			sortingFields.Add(new BXParamValue(GetMessageRaw("ActiveFromDate"), "ActiveFromDate"));
			sortingFields.Add(new BXParamValue(GetMessageRaw("ActiveUntilDate"), "ActiveToDate"));
			sortingFields.Add(new BXParamValue(GetMessageRaw("SortIndex"), "Sort"));
			sortingFields.Add(new BXParamValue(GetMessageRaw("DateOfModification"), "UpdateDate"));
			sortingFields.AddRange(sortProperties);

			ParamsDefinition["SortBy"].Values = sortingFields;


		}

		public class ElementListItem
		{
			private BXIBlockElement element;
			public BXIBlockElement Element
			{
				get { return element; }
				set { element = value; }
			}

			private string elementDetailUrl;
			public string ElementDetailUrl
			{
				get { return elementDetailUrl; }
				set { elementDetailUrl = value; }
			}

			private List<ElementListItemProperty> properties;
			public List<ElementListItemProperty> Properties
			{
				get { return properties; }
				set { properties = value; }
			}
		}

		public class ElementListItemProperty
		{
			BXCustomField field;
			public BXCustomField Field
			{
				set { field = value; }
				get { return field; }
			}

			BXCustomProperty property;
			public BXCustomProperty Property
			{
				set { property = value; }
				get { return property; }
			}

			private string name;
			public string Name
			{
				set { name = value; }
				get { return name; }
			}

			private string code;
			public string Code
			{
				get { return code; }
				set { code = value; }
			}

			private List<object> values;
			public List<object> Values
			{
				get { return values; }
				set { values = value; }
			}

			private string displayValue;
			public string DisplayValue
			{
				get { return displayValue; }
				set { displayValue = value; }
			}
		}
	}

	public class CatalogueElementListTemplate : BXComponentTemplate<CatalogueElementListComponent>
	{
		protected override void Render(HtmlTextWriter writer)
		{
			StartWidth = "100%";
			if (IsComponentDesignMode && Component.Items == null)
				writer.Write(BXLoc.GetMessage(Component, "YouHaveToAdjustTheComponent"));
			else
				base.Render(writer);
		}
	}

}
