using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.SessionState;
using DebriefingSoftware.Common.Web.Navigation;

namespace B4Restore.Common.Web
{
    public class NavigateParams : IRequiresSessionState
    {
        #region Public utility methods

        public static string AddParam(string navigateUrl, string paramName, string paramValue)
        {
            var result = navigateUrl;
            if (result.IndexOf('?') > 0)
            {
                if (!result.EndsWith("&") && !result.EndsWith("?"))
                    result = navigateUrl + '&';
                result = result +
                            String.Format("{0}={1}&", paramName, paramValue);
            }
            else
                result = result + '?' +
                            String.Format("{0}={1}&", paramName, paramValue);

            return result;
        }

        protected static string ReplaceParam(string navigateUrl, string paramName, string paramValue)
        {
            var iStartPos = navigateUrl.IndexOf(paramName, StringComparison.OrdinalIgnoreCase);
            var iEndPos = navigateUrl.IndexOf('&', iStartPos);
            if (iEndPos < 0)
                iEndPos = navigateUrl.Length;

            var result = navigateUrl.Remove(iStartPos, iEndPos - iStartPos);
            result = result.Insert(iStartPos, String.Format("{0}={1}", paramName, paramValue));

            return result;
        }

        public static string RemoveParam(string navigateUrl, string paramName)
        {
            var iStartPos = navigateUrl.IndexOf(paramName, StringComparison.OrdinalIgnoreCase);
            if (iStartPos < 0)
                return navigateUrl;

            var iEndPos = navigateUrl.IndexOf('&', iStartPos);
            if (iEndPos == navigateUrl.Length && navigateUrl.Length > 0)
                iEndPos--;

            if (iEndPos < 0)
                iEndPos = navigateUrl.Length - 1;

            var result = navigateUrl.Remove(iStartPos, iEndPos - iStartPos + 1);

            return result;
        }

        public static string RemoveParamAndSession(string navigateUrl, string paramName)
        {
            string result = NavigateParams.RemoveParam(navigateUrl, paramName);
            HttpContext.Current.Session.Remove(paramName);
            return result;
        }

        public static void RemoveParamFromSessionOnly(string paramName)
        {
            HttpContext.Current.Session.Remove(paramName);
        }


        public static string SetValue(string navigateUrl, string paramName, string paramValue, bool valueIsNull)
        {
            var result = navigateUrl;

            var iPos = result.IndexOf(paramName, 0, StringComparison.OrdinalIgnoreCase);
            if (iPos < 0)
            {
                if (!valueIsNull)
                    result = AddParam(result, paramName, paramValue);
            }
            else if (!valueIsNull)
                result = ReplaceParam(result, paramName, paramValue);
            else
                result = RemoveParam(result, paramName);

            return result;
        }

        #endregion

        public static string CurrentNavigateUrl
        {
            get
            {
                var result = (string)HttpContext.Current.Session["NavigateParams.CurrentNavigateUrl"];
                if (string.IsNullOrEmpty(result))
                {
                    result = HttpContext.Current.Request.RawUrl;
                    HttpContext.Current.Session["NavigateParams.CurrentNavigateUrl"] = result;
                }
                return result;
            }
            set { HttpContext.Current.Session["NavigateParams.CurrentNavigateUrl"] = value; }
        }

        public static void Clear()
        {
            HttpContext.Current.Session.Remove("NavigateParams.CurrentNavigateUrl");
        }

        protected static void AddParam(string paramName, string paramValue)
        {
            CurrentNavigateUrl = AddParam(CurrentNavigateUrl, paramName, paramValue);
        }

        protected static void ReplaceParam(string paramName, string paramValue)
        {
            CurrentNavigateUrl = ReplaceParam(CurrentNavigateUrl, paramName, paramValue);
        }

        public static void RemoveParam(string paramName)
        {
            CurrentNavigateUrl = RemoveParam(CurrentNavigateUrl, paramName);
        }

        public static void SetValue(string paramName, string paramValue, bool valueIsNull)
        {
            CurrentNavigateUrl = SetValue(CurrentNavigateUrl, paramName, paramValue, valueIsNull);
        }

        public static void NavigateToPage(string where)
        {
            HttpContext.Current.Response.Redirect(HttpContext.Current.Response.ApplyAppPathModifier(where));
        }

        public static string MenuPassiveClickRelUrl(string pageUrl, string queryParams)
        {
            return String.Format("javascript:tv_NodePassiveClickRelUrl(\"{0}?{1}\")", pageUrl, queryParams);
        }

        public static string MenuPassiveClickRelUrl(string pageUrl, Dictionary<string, string> param)
        {
            return MenuPassiveClickRelUrl(pageUrl, param, false);
        }

        public static string MenuPassiveClickRelUrl(string pageUrl, Dictionary<string, string> param, bool encodeParams)
        {
            string ret = QueryParamsToString(param, encodeParams);
            return MenuPassiveClickRelUrl(pageUrl, ret);
        }

        public static string QueryParamsToString(Dictionary<string, string> param, bool encodeParams)
        {
            var queryParams = new StringBuilder();
            foreach (var dictionary in param)
                queryParams.AppendFormat("{0}={1}&", dictionary.Key, dictionary.Value);
            string ret;
            if (encodeParams)
                ret = queryParams.ToString().EscapeUriStringOnce();
            else
                ret = queryParams.ToString();
            return ret;
        }

        public static string ApplyQueryParamsTo(string pageUrl, Dictionary<string, string> param)
        {
            var queryParams = new StringBuilder();
            foreach (var dictionary in param)
                queryParams.AppendFormat("{0}={1}&", dictionary.Key, dictionary.Value);
            return string.Format("{0}?{1}",
                                        pageUrl,
                                        queryParams).EscapeUriStringOnce().ApplyAppPathModifier();
        }
    }
}