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 LanguagePack;
using System.Web.Configuration;
using System.Xml;
using System.IO;
using System.Data.SqlClient;
using Spaces;
using System.Data.Common;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.Data.OleDb;
using System.Collections.Generic;
using System.Text;

public partial class Install_Install : System.Web.UI.Page
{
    private string m_loadMessage = "";
    protected void Page_Load(object sender, EventArgs e)
    {
        Wizard.NextButtonClick += new WizardNavigationEventHandler(Wizard_NextButtonClick);
        Wizard.PreviousButtonClick += new WizardNavigationEventHandler(Wizard_PreviousButtonClick);
        Wizard.ActiveStepChanged += new EventHandler(Wizard_ActiveStepChanged);
        Wizard.FinishButtonClick +=new WizardNavigationEventHandler(Wizard_FinishButtonClick);
        if (!IsPostBack)
        {
            BindData();
        }       
    }
    
    void Wizard_NextButtonClick(object sender, WizardNavigationEventArgs e)
    {
        e.Cancel = true;
        try
        {
            switch (e.CurrentStepIndex)
            {
                case 0:
                        e.Cancel = false;
                    break;
                case 1:
                    if (UpdateConfig())
                        e.Cancel = false;
                    break;
               
                case 2:
                    if (DatabaseConfig())
                        e.Cancel = false;
                    break;
                case 3:
                    if (UpgradeDatabase())
                        e.Cancel = false;
                    Wizard.StepPreviousButtonStyle.CssClass = "hide" ;
                    break;
                case 4:
                    if (SetAdmin())
                        e.Cancel = false;
                    break;
            }
        }
        catch (Exception x)
        {
            AddLoadMessage(x.Message);
        }
        e.Cancel = false;
    }

    private bool SetAdmin()
    {
        if (IsSpacesInstalled)
        {
            AddLoadMessage("i-favourite 已经安装！");
            return false;
        }
        #region 插入管理员
        string password = Des.Encrypt(txtAdminPassword.Text, "xiaoxiao");
        string sql = string.Format(@"INSERT INTO tbl_Admin([Username], [Password])
        VALUES('{0}','{1}')", Utils.SqlInput(txtAdminUser.Text), password);
        if (Config.GetConfig().DefaultProvider == "MySql")
            sql = string.Format(@"INSERT INTO tbl_Admin(`Username`, `Password`)
        VALUES('{0}','{1}')", Utils.SqlInput(txtAdminUser.Text), password);
        SpacesDataProvider.Instance().ExecuteNonQuery(sql);
        #endregion
        return true;
    }

    private bool UpgradeDatabase()
    {
        try
        {
            ConfigurationManager.RefreshSection("disk/disk");
            string script = "";
                switch(Config.GetConfig().DefaultProvider)
                {
                    case "SqlServer" :
                         script = "sqlserver.sql";
                         ExecuteSqlServerScript(script);
                        break;
                    case "MySql" :
                        script = "mysql.sql";
                        ExecuteMySqlScript(script);
                        break;
                    case "Access":
                        string source = Request.MapPath("DataBase.mdb");
                        string toPut = txtDBPath.Text;
                        File.Copy(source, toPut, false);
                        break;
                }

            }
        catch (Exception x)
        {
            AddLoadMessage(x.Message);
            return false;
        }
        return true;
    }

    private bool DatabaseConfig()
    {
        if (IsSpacesInstalled)
        {
            AddLoadMessage("i-favourite 已经安装！");
            return false;
        }
        string rootPath = Server.MapPath("~/");
        if (!rootPath.EndsWith("\\"))
            rootPath += "\\";

        try
        {
            string provider = dropDatabase.SelectedValue;
            XmlDocument doc = new XmlDocument();
            FileInfo xmlFile = new FileInfo(string.Format("{0}Web.Config", rootPath));
            if (!xmlFile.Exists)
            {
                throw new ApplicationException("没有找到配置文件");
            }
            doc.Load(xmlFile.FullName);
            XmlNode node = doc["configuration"]["disk"]["disk"];
            node.Attributes["defaultProvider"].Value = provider;


            XmlNodeList ns = node["providers"].ChildNodes;
            foreach (XmlNode r in ns)
            {
                if (r.Attributes["name"] != null)
                {

                    if (r.Attributes["name"].Value == provider)
                    {
                        r.Attributes["connectionString"].Value =GetConnString(provider) ;
                    }
                }
            }
            doc.Save(xmlFile.FullName);
            ConfigurationManager.RefreshSection("disk/disk");
            return true;
        }
        catch (Exception ex)
        {
            AddLoadMessage(ex.Message);
            //throw ex;
            return false;
        }
       
    }

    private string GetConnString(string provider)
    {
        string connstr = string.Empty;
        string sqlServerConn = "server={0};database={1};uid={2};pwd={3}";
        string accessConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}";
        string mySqlConn = "User Id={2};Password={3};Host={0};Database={1};charset={4};";

        string dbPath =txtDBPath.Text;
        string server = txtDBServer.Text;
        string userID = txtDBUsername.Text;
        string pwd = txtDBPassword.Text;
        string dbName = txtDBName.Text;
        string charset = DropDBCharset.SelectedValue;
        switch (provider)
        { 
            case "Access":
                connstr = string.Format(accessConn, dbPath);
                break;
            case "MySql":
                connstr = string.Format(mySqlConn,server,dbName,userID,pwd,charset);
                break;
            case "SqlServer":
                connstr = string.Format(sqlServerConn, server, dbName, userID, pwd);
                break;
        
        }
        return connstr;
    }
    bool IsSpacesInstalled
    {
        get { return false; }
    }
    bool UpdateConfig()
    {

        if (IsSpacesInstalled)
            {
                AddLoadMessage("i-favourite 已经安装！");
                return false;
            }
            string rootPath = Server.MapPath("~/");
            if (!rootPath.EndsWith("\\"))
                rootPath += "\\";
            string diskPath = txtDiskPath.Text;
            string domain = txtDefaultDomain.Text;
            string music = txtDefaultMusic.Text;
            string album = txtDefaultAlbum.Text;
            string albumPath = txtBlogAlbumPath.Text;
            string albumUrl = txtBlogAlbumUrl.Text;
            string language = dropLanguages.SelectedValue;
            string domainFix = txtDomainFix.Text;

            string photoPath = txtPhotosPath.Text;
            string photoUrl = txtPhotosUrl.Text;
            bool enableDisku = chkEnableDisku.Checked;
            if (!albumUrl.EndsWith("/"))
                albumUrl += "/";
            if (diskPath.Length == 0)
            {
                AddLoadMessage("请填写网络U盘目录地址！");
                return false;
            }
        try
        {
            if (!Directory.Exists(photoPath))
            {
                Directory.CreateDirectory(photoPath);
            }
            XmlDocument doc = new XmlDocument();

            FileInfo xmlFile = new FileInfo(string.Format("{0}Web.Config", rootPath));
            if (!xmlFile.Exists)
            {
                throw new ApplicationException("没有找到配置文件");
            }
            doc.Load(xmlFile.FullName);
            XmlNode node = doc["configuration"]["disk"]["disk"];
            string userPath = diskPath;
            if (!Directory.Exists(userPath))
                Directory.CreateDirectory(userPath);
            node.Attributes["userPasswordFormat"].Value = DropUserPasswordFormat.SelectedValue;
            node.Attributes["photosPath"].Value =photoPath;
            node.Attributes["photosUrl"].Value = photoUrl;
            node.Attributes["uploadFilesPath"].Value = userPath;
            node.Attributes["defaultDomain"].Value = domain;

            string blogimageFolder = albumPath;
            if (!Directory.Exists(blogimageFolder))
                Directory.CreateDirectory(blogimageFolder);

            node.Attributes["blogAlbumPath"].Value = blogimageFolder;

            node.Attributes["blogAlbumUrl"].Value = albumUrl;

            node.Attributes["defaultLanguage"].Value = language;

            node.Attributes["defaultMusic"].Value=music;
            node.Attributes["defaultAlbum"].Value=album;
            node.Attributes["domainFix"].Value = domainFix;
            node.Attributes["enableDisk"].Value = enableDisku.ToString();
            doc.Save(xmlFile.FullName);
            return true;
        }
        catch (Exception ex)
        {
            throw ex;
        }

      
    }
    void Wizard_ActiveStepChanged(object sender, EventArgs e)
    {
       // Wizard.ActiveStepIndex++;
    }

    void Wizard_PreviousButtonClick(object sender, WizardNavigationEventArgs e)
    {
       
    }

    
    void BindData()
    {
        dropLanguages.Items.Clear();
        foreach (string s in Resources.SupportLanguages.Keys)
        {
            ListItem li = new ListItem(Resources.SupportLanguages[s], s);
            dropLanguages.Items.Add(li);
        }
        string domain = Request.ServerVariables["HTTP_HOST"];
        domain = string.Format("http://{0}",domain);
        string rootPath = Server.MapPath("~/");
        if(!rootPath.EndsWith("\\"))
            rootPath+="\\";
        this.lSitePath.Text = rootPath;
        txtDiskPath.Text = string.Format("{0}Users", rootPath);
        txtDefaultDomain.Text = string.Format("{0}{1}/{2}/default.aspx",domain, Globals.ApplicationPath,"{0}");
        txtDefaultMusic.Text = "我的音乐盒";
        txtDefaultAlbum.Text = "我的图库";
        txtBlogAlbumPath.Text = string.Format("{0}BlogImage",rootPath);
        string albumUrl = Globals.ApplicationPath + "/BlogImage";
        albumUrl =albumUrl.Replace("//","/");
        txtBlogAlbumUrl.Text =string.Format("{0}{1}",domain,albumUrl ) ;
        txtDBPath.Text = string.Format("{0}myblog.Config", rootPath);
        txtDBServer.Text = "localhost";
        txtDBUsername.Text = "sa";
        txtDBName.Text = "I_Favourite";
        txtPhotosPath.Text = string.Format("{0}Photos", rootPath);
        txtPhotosUrl.Text = string.Format("{0}/Photos", domain);
        //设置域前缀
        string host = Request.Url.Host;
        List<string> fixs = new List<string>();
        if (host.IndexOf(".") != -1)
        {
            string[] ds = host.Split('.');
            fixs.Add(ds[0]);
            if (ds.Length > 1)
            {
                fixs.Add(ds[1]);
            }
        }
        if (!fixs.Contains("www"))
            fixs.Add("www");
        if (!fixs.Contains("localhost"))
            fixs.Add("localhost");
        if (!fixs.Contains("127"))
            fixs.Add("127");
        if (!fixs.Contains("192"))
            fixs.Add("192");
        if (!fixs.Contains("10"))
            fixs.Add("10");
        StringBuilder sb = new StringBuilder();
        foreach (string s in fixs)
        {
            sb.AppendFormat("{0}|",s);
        }
        if (sb.Length > 1)
            sb.Remove(sb.Length-1,1);
        txtDomainFix.Text = sb.ToString();
        Wizard.StartNextButtonText = "同意该协议，继续安装";
    }
    protected void Wizard_FinishButtonClick(object sender, WizardNavigationEventArgs e)
    {
        Response.Redirect("~/");
    }

    #region 消息


    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        base.Render(writer);
        if (m_loadMessage != "")
        {
            writer.WriteLine("<script language='javascript'>");
            writer.WriteLine("onload = function() {");
            writer.WriteLine("	alert('{0}');", m_loadMessage);
            writer.WriteLine("}");
            writer.WriteLine("</script>");
        }
    }
    #endregion

    #region method AddLoadMessage
    void AddLoadMessage(string msg)
    {
        msg = msg.Replace("\\", "\\\\");
        msg = msg.Replace("'", "\\'");
        msg = msg.Replace("\r\n", "\\r\\n");
        msg = msg.Replace("\n", "\\n");
        msg = msg.Replace("\"", "\\\"");
        m_loadMessage += msg + "\\n\\n";
    }
    #endregion

    #region method ExecuteScript
    private void ExecuteSqlServerScript(string sScriptFile)
    {

        string sScript = null;
        try
        {
            using (System.IO.StreamReader file = new System.IO.StreamReader(Request.MapPath(sScriptFile)))
            {
                sScript = file.ReadToEnd() + "\r\n";
                file.Close();
            }
        }
        catch (System.IO.FileNotFoundException)
        {
            return;
        }
        catch (Exception x)
        {
            throw new Exception("Failed to read " + sScriptFile, x);
        }

        string[] statements = System.Text.RegularExpressions.Regex.Split(sScript, "\\sGO\\s", System.Text.RegularExpressions.RegexOptions.IgnoreCase);

        using (SqlConnection conn = (SqlConnection)GetConnection())
        {
            using (SqlTransaction trans = conn.BeginTransaction())
            {
                foreach (string sql0 in statements)
                {
                    string sql = sql0.Trim();

                    try
                    {
                        if (sql.ToLower().IndexOf("setuser") >= 0)
                            continue;

                        if (sql.Length > 0)
                        {
                            using (SqlCommand cmd = new SqlCommand())
                            {
                                cmd.Transaction = trans;
                                cmd.Connection = conn;
                                cmd.CommandType = CommandType.Text;
                                cmd.CommandText = sql.Trim();
                                cmd.ExecuteNonQuery();
                            }
                        }
                    }
                    catch (Exception x)
                    {
                        trans.Rollback();
                        throw new Exception(String.Format("FILE:\n{0}\n\nERROR:\n{2}\n\nSTATEMENT:\n{1}", sScriptFile, sql, x.Message));
                    }
                }
                trans.Commit();
            }
        }

    }
    private void ExecuteMySqlScript(string sScriptFile)
    {

        string sScript = null;
        try
        {
            using (System.IO.StreamReader file = new System.IO.StreamReader(Request.MapPath(sScriptFile)))
            {
                sScript = file.ReadToEnd() + "\r\n";
                file.Close();
            }
        }
        catch (System.IO.FileNotFoundException)
        {
            return;
        }
        catch (Exception x)
        {
            throw new Exception("Failed to read " + sScriptFile, x);
        }

       // string[] statements = System.Text.RegularExpressions.Regex.Split(sScript, "\\sGO\\s", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string sql = sScript;
        using (MySqlConnection conn =  (MySqlConnection)GetConnection())
        {
            using (MySqlTransaction trans = conn.BeginTransaction())
            {
                try
                {
                    
                   

                    if (sql.Length > 0)
                    {
                        using (MySqlCommand cmd = new MySqlCommand())
                        {
                            cmd.Transaction = trans;
                            cmd.Connection = conn;
                            cmd.CommandType = CommandType.Text;
                            cmd.CommandText = sql.Trim();
                            cmd.ExecuteNonQuery();
                        }
                    }
                }
                catch (Exception x)
                {
                    trans.Rollback();
                    throw new Exception(String.Format("FILE:\n{0}\n\nERROR:\n{2}\n\nSTATEMENT:\n{1}", sScriptFile, sql, x.Message));
                }
                /*
                foreach (string sql0 in statements)
                {
                    string sql = sql0.Trim();

                    try
                    {
                        if (sql.ToLower().IndexOf("setuser") >= 0)
                            continue;

                        if (sql.Length > 0)
                        {
                            using (MySqlCommand cmd = new MySqlCommand())
                            {
                                cmd.Transaction = trans;
                                cmd.Connection = conn;
                                cmd.CommandType = CommandType.Text;
                                cmd.CommandText = sql.Trim();
                                cmd.ExecuteNonQuery();
                            }
                        }
                    }
                    catch (Exception x)
                    {
                        trans.Rollback();
                        throw new Exception(String.Format("FILE:\n{0}\n\nERROR:\n{2}\n\nSTATEMENT:\n{1}", sScriptFile, sql, x.Message));
                    }
                }
                 * */
                trans.Commit();
            }
        }

    }
    #endregion

    public static IDbConnection GetConnection()
    {
        Config config=Config.GetConfig();
        IDbConnection conn=null;
        string connstr=config.Providers[config.DefaultProvider].Attributes["connectionString"];
        switch (config.DefaultProvider)
        {
            case "Access":
                conn = new OleDbConnection(connstr);
                break;
            case "MySql":
                conn = new MySqlConnection(connstr);
                break;
            case "SqlServer":
                conn = new SqlConnection(connstr);
                break;
        }
        conn.Open();
        return (IDbConnection)conn;
    }

}
