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.Security;
using Bitrix.IO;
using Bitrix.Configuration;
using System.IO;
using System.Text;
using Bitrix;
using System.Collections.Generic;
using System.Web.SessionState;
using Bitrix.DataTypes;
using System.Web.Hosting;

public partial class bitrix_dialogs_DeletePage : BXDialogPage
{
    /// <summary>
    /// Путь к удаляемой странице
    /// </summary>
    private string mPath = null;
    /// <summary>
    /// Путь к директории (часть Path)
    /// </summary>
    private string mDirectoryPath = null;

    /// <summary>
    /// Имя файла (часть Path)
    /// </summary>
    private string mFileName = null;
    private List<string> mPathList = null;

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

        try
        {
            //if (!BXUser.IsCanOperate(BXRoleOperation.Operations.FileManage))
            //    Close(GetMessage("INSUFFICIENT_RIGHTS"), BXDialogGoodbyeWindow.LayoutType.Error, -1);

            mPath = Request["path"];
            if (string.IsNullOrEmpty(mPath))
                Close(GetMessage("PATH_IS_NOT_SPECIFIED"), BXDialogGoodbyeWindow.LayoutType.Error, -1);


            bool isPathValid = false;
            try
            {
                isPathValid = VirtualPathUtility.IsAppRelative(mPath);
            }
            catch (Exception /*exc*/){ }

            if(!isPathValid)
                Close(GetMessage("PATH_IS_NOT_VALID"), BXDialogGoodbyeWindow.LayoutType.Error, -1);


            string phPath = HostingEnvironment.MapPath(mPath);
            if (Directory.Exists(phPath))
            {
                mDirectoryPath = VirtualPathUtility.AppendTrailingSlash(mPath);
                mPath = VirtualPathUtility.Combine(mDirectoryPath, BXConfigurationUtility.Constants.DefaultPage);            }
            else if (File.Exists(phPath))
            {
                mDirectoryPath = VirtualPathUtility.GetDirectory(mPath);
                //mDirectoryPath = VirtualPathUtility.AppendTrailingSlash(mDirectoryPath); //страховка
            }

            if (string.IsNullOrEmpty(mDirectoryPath))
                Close(string.Format("{0}: {1}!", GetMessage("DIRECTORY_IS_NOT_SPECIFIED_IN_PATH"), mPath));


            mFileName = VirtualPathUtility.GetFileName(mPath);
            if (string.IsNullOrEmpty(mFileName))
                Close(string.Format("{0}: {1}!", GetMessage("FILE_NAME_IS_NOT_SPECIFIED_IN_PATH"), mPath));

            DescriptionIconClass = "bx-delete-page";
            DescriptionParagraphs.Add(string.Format("{0} <b>{1}</b>?", GetMessage("DO_YOU_REALLY_WANT_DELETE_PAGE"), mPath));
            //предупреждение об удалении страницы по умолчанию
            defaultPageDeletionAlert.Visible = IsDefaultFileName;
            //удаление соотв. пунктов меню
            deleteMenuItem.Visible = true;/*IsPathPresentInMenu;*/

            if (!defaultPageDeletionAlert.Visible && !deleteMenuItem.Visible)
                scriptContainer.InnerHtml = "<script type='text/javascript'>jsPopup.HideDialogContent();</script>";
            Behaviour.ButonSetLayout = BXPageAsDialogButtonSetLayout.YesNo;
            Behaviour.SetButtonText(BXPageAsDialogButtonEntry.Yes, GetMessageRaw("ButtonText.YesDelete"));
            Behaviour.SetButtonText(BXPageAsDialogButtonEntry.No, GetMessageRaw("ButtonText.DontDelete"));

            Behaviour.Settings.MinWidth = 600;
            Behaviour.Settings.Width = 600;
            Behaviour.Settings.Height = 0;
            Behaviour.Settings.Resizeable = false;
        }
        catch (System.Threading.ThreadAbortException /*exception*/)
        {
            //...игнорируем, вызвано Close();
        }
        catch (Exception exception)
        {
            Close(exception.Message, BXDialogGoodbyeWindow.LayoutType.Error, -1);
        }
    }


    protected override string GetParametersBagName()
    {
        return "BitrixDialogDeletePageParamsBag";
    }

    protected override void ExternalizeParameters(BXParamsBag<string> paramsBag)
    {
        if (paramsBag == null)
            throw new ArgumentNullException("paramsBag");

        paramsBag.Add(deleteMenuItemChkBx.ID, deleteMenuItemChkBx.Checked.ToString());
    }

    protected override void InternalizeParameters(BXParamsBag<string> paramsBag)
    {
        if (paramsBag == null)
            throw new ArgumentNullException("paramsBag");

        if (paramsBag.ContainsKey(deleteMenuItemChkBx.ID))
            deleteMenuItemChkBx.Checked = Convert.ToBoolean(paramsBag[deleteMenuItemChkBx.ID]);
    }

    protected bool IsDefaultFileName
    {
        get
        {
            if (string.IsNullOrEmpty(mFileName))
                throw new InvalidOperationException("Could not find file name!");
            return string.Compare(mFileName, BXConfigurationUtility.Constants.DefaultPage, StringComparison.OrdinalIgnoreCase) == 0;
        }
    }

    //protected bool IsPathPresentInMenu
    //{
    //    get 
    //    {
    //        if (string.IsNullOrEmpty(mPath))
    //            throw new InvalidOperationException("Could not find path!");

    //        List<BXMenu> resultLst = new List<BXMenu>();
    //        BXMenuManager.MenuPair[] menuIdArr = BXMenuManager.GetMenuTypes(BXSite.Current.Id);
    //        int menuCount = menuIdArr != null ? menuIdArr.Length : 0;
    //        for (int i = 0; i < menuCount; i++)
    //        {
    //            BXMenuManager.MenuPair menuId = menuIdArr[i];
    //            BXMenu menu = BXMenuManager.Load(mPath, menuId.Id, 1);
    //            int menuItemCount = menu != null ? menu.Count : 0;
    //            for (int j = 0; j < menuItemCount; j++)
    //            {
    //                BXMenuItem menuItem = menu[j];

    //                string menuItemPath = menuItem.Link;

    //                menuItemPath = BXPath.ToVirtualRelativePath(menuItem.Link);
    //                if (string.Compare(menuItemPath, mPath, StringComparison.OrdinalIgnoreCase) == 0 ||
    //                    (IsDefaultFileName && 
    //                    string.Compare(menuItemPath, mDirectoryPath, StringComparison.OrdinalIgnoreCase) == 0)
    //                    ) 
    //                    return true;
    //            }
    //        }
    //        return false;
    //    }
    //}

    //private List<string> handledMenuPathList = null;

    protected void RemovePathFromMenus(string virtualDirectoryPath)
    {
        if (string.IsNullOrEmpty(mPath))
            throw new ArgumentException("Is not specified!", "mPath");
        //---
        if (string.IsNullOrEmpty(mDirectoryPath))
            throw new ArgumentException("Is not specified!", "mDirectoryPath");
        //---

        if (string.IsNullOrEmpty(virtualDirectoryPath))
            throw new ArgumentException("Is not specified!", "virtualDirectoryPath");
        //---

        BXSite site = BXSite.GetCurrentSite(virtualDirectoryPath, Request.Url.Host);
        if (site == null)
            throw new InvalidOperationException(string.Format("Could not find site for path '{0}'!", virtualDirectoryPath));
        //---

        Dictionary<string, string> menuTypeDic = BXPublicMenu.GetMenuTypes(site.Id);
        foreach (string key in menuTypeDic.Keys)
        {
            //BXMenuManager.MenuPair menuId = menuIdArr[i];
            string menuId = key;
            BXPublicMenuItemCollection menuItemCol = null;
            try
            {
                menuItemCol = BXPublicMenu.Menu.GetMenuByUri(menuId, virtualDirectoryPath);
            }
            catch (Exception /*exception*/)
            {
                menuItemCol = null;
            }

            if (menuItemCol == null || menuItemCol.Count == 0)
                continue;

            if (!string.IsNullOrEmpty(menuItemCol.MenuFilePath) &&
                mPathList != null &&
               mPathList.FindIndex(
                   delegate(string curPath)
                   { return string.Compare(menuItemCol.MenuFilePath, curPath, StringComparison.OrdinalIgnoreCase) == 0; }
               ) >= 0)
                continue;

            bool menuChanged = false;
            int j = 0;

            while (j < menuItemCol.Count)
            {
                BXPublicMenuItem menuItem = menuItemCol[j];
                string menuItemPath = null;

                if (!string.IsNullOrEmpty(menuItem.Link))
                    try
                    {
                        int whatInd = menuItem.Link.IndexOf('?');
                        if (whatInd < 0)
                            menuItemPath = BXPath.ToVirtualRelativePath(menuItem.Link);
                        else
                            menuItemPath = BXPath.ToVirtualRelativePath(menuItem.Link.Substring(0, whatInd));
                    }
                    catch (Exception /*exception*/)
                    {
                        menuItemPath = null;
                    }

                bool aboutDelete = false;
                if (!string.IsNullOrEmpty(menuItemPath))
                {
                    if (string.Equals(mFileName, BXConfigurationUtility.Constants.DefaultPage, StringComparison.OrdinalIgnoreCase))
                        aboutDelete = string.Equals(VirtualPathUtility.AppendTrailingSlash(menuItemPath), mDirectoryPath, StringComparison.OrdinalIgnoreCase);
                    
                    if(!aboutDelete)
                        aboutDelete = string.Equals(VirtualPathUtility.RemoveTrailingSlash(menuItemPath), mPath, StringComparison.OrdinalIgnoreCase);
                }

                if (!aboutDelete)
                {
                    j++;
                    continue; 
                }

                menuItemCol.RemoveAt(j);

                if (!menuChanged)
                    menuChanged = true;
            }

            if (menuChanged)
            {
                //if (string.IsNullOrEmpty(menuItemCol.MenuFilePath))
                //    BXPublicMenu.Menu.ClearMenu(menuItemCol.MenuFilePath);
                //Bitrix.Diagnostics.BXDump.ToFile("DeletePage: Before menu save" + BXPublicMenu.Menu.Dump(false));
                BXPublicMenu.Menu.Save(virtualDirectoryPath, menuId, menuItemCol);
                //Bitrix.Diagnostics.BXDump.ToFile("DeletePage: After menu save" + BXPublicMenu.Menu.Dump(false));
            }
            if (mPathList == null)
                mPathList = new List<string>();

            if (!string.IsNullOrEmpty(menuItemCol.MenuFilePath) &&
                mPathList.FindIndex(
                    delegate(string curPath)
                    { return string.Compare(menuItemCol.MenuFilePath, curPath, StringComparison.OrdinalIgnoreCase) == 0; }
                ) < 0) 
                mPathList.Add(menuItemCol.MenuFilePath);
        }

        string physicalPath = BXPath.ToPhysicalPath(virtualDirectoryPath);
        string[] childDirectories = Directory.GetDirectories(physicalPath);
        int childDirectoriesCount = childDirectories != null ? childDirectories.Length : 0;

        for (int i = 0; i < childDirectoriesCount; i++)
        {
            ///HACK: Ignoring service derectories
            string childDirectoryVirtualPath = BXPath.ToVirtualRelativePath(childDirectories[i]);
            if (string.Compare(childDirectoryVirtualPath, "~/app_browsers", StringComparison.OrdinalIgnoreCase) == 0 || 
                childDirectoryVirtualPath.StartsWith("~/app_browsers/", StringComparison.OrdinalIgnoreCase) ||
                string.Compare(childDirectoryVirtualPath, "~/app_data", StringComparison.OrdinalIgnoreCase) == 0 || 
                childDirectoryVirtualPath.StartsWith("~/app_data/", StringComparison.OrdinalIgnoreCase) ||
                string.Compare(childDirectoryVirtualPath, "~/app_themes", StringComparison.OrdinalIgnoreCase) == 0 || 
                childDirectoryVirtualPath.StartsWith("~/app_themes/", StringComparison.OrdinalIgnoreCase) ||
                string.Compare(childDirectoryVirtualPath, "~/bin", StringComparison.OrdinalIgnoreCase) == 0 || 
                childDirectoryVirtualPath.StartsWith("~/bin/", StringComparison.OrdinalIgnoreCase) ||
                string.Compare(childDirectoryVirtualPath, "~/bitrix", StringComparison.OrdinalIgnoreCase) == 0 || 
                childDirectoryVirtualPath.StartsWith("~/bitrix/", StringComparison.OrdinalIgnoreCase) ||
                string.Compare(childDirectoryVirtualPath, "~/upload", StringComparison.OrdinalIgnoreCase) == 0 || 
                childDirectoryVirtualPath.StartsWith("~/upload/", StringComparison.OrdinalIgnoreCase))
                continue;

            RemovePathFromMenus(childDirectoryVirtualPath);
        }
    }
    protected void Behaviour_Yes(object sender, EventArgs e)
    {
        try
        {
            BXUser.DemandOperations(BXRoleOperation.Operations.FileManage);

            if (string.IsNullOrEmpty(mPath))
                throw new InvalidOperationException("Could not find path!");

            string phPath = BXPath.ToPhysicalPath(mPath);
            FileInfo fi = new FileInfo(phPath);
            if (!fi.Exists)
                Close(GetMessage("PATH_IS_NOT_EXISTS"), BXDialogGoodbyeWindow.LayoutType.Error, -1);

            string ext = fi.Extension;

            if (string.Compare(ext, ".aspx", StringComparison.OrdinalIgnoreCase) != 0)
                Close(GetMessage("FILE_HAS_INVALID_EXTENSION"), BXDialogGoodbyeWindow.LayoutType.Error, -1);

            if (string.IsNullOrEmpty(mDirectoryPath))
                throw new InvalidOperationException("Could not find directory path!");

            //если удаляем страницу по умолчанию, то текущим каталогом сразу становиться родительский каталог
            //if(string.Equals(mFileName, BXConfigurationUtility.Constants.DefaultPage, StringComparison.InvariantCultureIgnoreCase))
            //    mDirectoryPath = VirtualPathUtility.GetDirectory(mDirectoryPath);
            //mDirectoryPath = VirtualPathUtility.AppendTrailingSlash(mDirectoryPath);

            //пытаемся перенаправить пользователя на страницу по умолчанию текущего каталога, если её не существует поднимаемся выше по дереву каталогов
            //если удаляем страницу по умолчанию, то текущим каталогом сразу становиться родительский каталог

            string redirectionDirPath = string.Equals(mFileName, BXConfigurationUtility.Constants.DefaultPage, StringComparison.InvariantCultureIgnoreCase) ? VirtualPathUtility.GetDirectory(mDirectoryPath) : mDirectoryPath;
            redirectionDirPath = VirtualPathUtility.AppendTrailingSlash(redirectionDirPath);
            string redirectionPath = VirtualPathUtility.Combine(redirectionDirPath, BXConfigurationUtility.Constants.DefaultPage);
            while (!BXSecureIO.FileExists(redirectionPath) && !string.Equals(VirtualPathUtility.RemoveTrailingSlash(redirectionDirPath), "~", StringComparison.Ordinal)) 
            {
                redirectionDirPath = VirtualPathUtility.GetDirectory(redirectionDirPath);
                redirectionPath = VirtualPathUtility.Combine(redirectionDirPath, BXConfigurationUtility.Constants.DefaultPage);
            }

            StringBuilder sb = new StringBuilder(VirtualPathUtility.ToAbsolute(redirectionPath));
            string showModeParamValue = BXConfigurationUtility.GetShowModeParamValue(BXConfigurationUtility.GetShowMode(sb.ToString()));
            sb.Append('?');
            sb.Append(HttpUtility.UrlEncode(BXConfigurationUtility.Constants.ShowModeParamName));
            sb.Append('=');
            sb.Append(HttpUtility.UrlEncode(showModeParamValue));

            BXSecureIO.FileDelete(phPath);

            if (deleteMenuItemChkBx.Checked)
            {
                if (mPathList != null && mPathList.Count > 0)
                    mPathList.Clear();
                RemovePathFromMenus("~");
            }

            Redirect(sb.ToString(), GetMessage("OPERATION_IS_COMPLETED_SUCCESSFULLY"), BXDialogGoodbyeWindow.LayoutType.Success, 800);
        }
        catch (System.Threading.ThreadAbortException /*exception*/)
        {
            //...игнорируем, вызвано Close();
        }
        catch (Exception exception)
        {
            ShowError(exception.Message);
        }
    }
}
