using System;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using FastReport.Utils;
using System.Collections.Generic;
using System.Reflection;

namespace FastReport.Forms
{
    internal partial class ReportOptionsForm : BaseDialogForm
    {
        private Report report;

        public Report Report
        {
            get { return report; }
            set { report = value; }
        }

        private void ReportOptionsForm_Shown(object sender, EventArgs e)
        {
            // needed for hidpi mode
        }

        private void ReportOptionsForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!Done())
                e.Cancel = true;
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Filter = Res.Get("FileFilters,Images");
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    pbPicture.Image = Image.FromFile(dialog.FileName);
                }
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            pbPicture.Image = null;
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Filter = Res.Get("FileFilters,Assembly");
                if (dialog.ShowDialog() == DialogResult.OK)
                    AddPlugin(dialog.FileName);
            }
        }


        private void BtnRemove_Click(object sender, System.EventArgs e)
        {
            if (dgRefAssemblies.SelectedRows.Count == 0)
                return;
            dgRefAssemblies.Rows.Remove(dgRefAssemblies.SelectedRows[0]);
        }

        private void tbPasswordLoad_TextChanged(object sender, EventArgs e)
        {
            tbRetypePassword.Text = "";
        }

        private void rbInherit_CheckedChanged(object sender, EventArgs e)
        {
            btnBrowse.Enabled = rbInherit.Checked;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Filter = Res.Get("FileFilters,Report");
                if (dialog.ShowDialog() == DialogResult.OK)
                    lblBaseName.Text = dialog.FileName;
                else
                    lblBaseName.Text = "";
            }
        }

        private void tbDescription_ButtonClick(object sender, EventArgs e)
        {
            using (StringCollectionEditorForm form = new StringCollectionEditorForm())
            {
                form.PlainText = tbDescription.Text;
                if (form.ShowDialog() == DialogResult.OK)
                    tbDescription.Text = form.PlainText;
            }
        }

        private void dgPlugins_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnRemove.Enabled = dgRefAssemblies.SelectedRows.Count != 0;
        }

        private string GetFullAssemblyReference(string relativeReference, string defaultPath)
        {
            // in .NET Core we get the AssemblyReference in FR.Compat
#if !(NETSTANDARD || NETCOREAPP)
            if (relativeReference == null || relativeReference.Trim() == "")
                return "";

            // Strip off any trailing ".dll" ".exe" if present.
            string dllName = relativeReference;
            if (string.Compare(relativeReference.Substring(relativeReference.Length - 4), ".dll", true) == 0 ||
              string.Compare(relativeReference.Substring(relativeReference.Length - 4), ".exe", true) == 0)
                dllName = relativeReference.Substring(0, relativeReference.Length - 4);

            // See if the required assembly is already present in our current AppDomain
            foreach (Assembly currAssembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (string.Compare(currAssembly.GetName().Name, dllName, true) == 0)
                {
                    // Found it, return the location as the full reference.
                    return currAssembly.Location;
                }
            }

            // See if the required assembly is present in the ReferencedAssemblies but not yet loaded
            foreach (AssemblyName assemblyName in Assembly.GetExecutingAssembly().GetReferencedAssemblies())
            {
                if (string.Compare(assemblyName.Name, dllName, true) == 0)
                {
                    // Found it, try to load assembly and return the location as the full reference.
                    try
                    {
                        return Assembly.ReflectionOnlyLoad(assemblyName.FullName).Location;
                    }
                    catch { }
                }
            }

            // See if the required assembly is present locally
            string path = Path.Combine(defaultPath, relativeReference);
            if (File.Exists(path))
                return path;
#endif
            return relativeReference;
        }

        private string GetToolTipText(string location)
        {
            if (location == null || !File.Exists(location)) return "";

            FileInfo info = new FileInfo(location);
            var versionInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(location);

            return  info.Name + "\n" +
                    Res.Get("Forms,PluginsOptions,Description") + " " +
                    versionInfo.FileDescription + "\n" +
                    Res.Get("Forms,PluginsOptions,CompanyName") + " " +
                    versionInfo.CompanyName + "\n" +
                    Res.Get("Forms,PluginsOptions,Version") + " " +
                    versionInfo.FileVersion + "\n" +
                    Res.Get("Forms,PluginsOptions,Date") + " " + info.CreationTime.ToString() + "\n" +
                    Res.Get("Forms,PluginsOptions,Size") + " " + FileSize.ConvertToString(info.Length) + "\n" +
                    Res.Get("Forms,PluginsOptions,Path") + "\n" + location;
        }

        private void AddPlugin(string location)
        {
            dgRefAssemblies.Rows.Add(Path.GetFileName(location));
            string toolTip = GetToolTipText(location);

            dgRefAssemblies.Rows[dgRefAssemblies.Rows.Count - 1].Cells[0].ToolTipText = toolTip;
        }

        private void Init()
        {
            cbDoublePass.Checked = Report.DoublePass;
            cbCompress.Checked = Report.Compressed;
            cbUseFileCache.Checked = Report.UseFileCache;
            cbConvertNulls.Checked = Report.ConvertNulls;
            cbxTextQuality.SelectedIndex = (int)Report.TextQuality;
            cbSmoothGraphics.Checked = Report.SmoothGraphics;

            tbName.Text = Report.ReportInfo.Name;
            tbAuthor.Text = Report.ReportInfo.Author;
            tbVersion.Text = Report.ReportInfo.Version;
            tbDescription.Text = Report.ReportInfo.Description;
            pbPicture.Image = Report.ReportInfo.Picture;
            cbSavePreviewPicture.Checked = Report.ReportInfo.SavePreviewPicture;
            lblCreated1.Text = Report.ReportInfo.Created.ToString();
            lblModified1.Text = Report.ReportInfo.Modified.ToString();

            rbC.Checked = Report.ScriptLanguage == Language.CSharp;
            rbVB.Checked = Report.ScriptLanguage == Language.Vb;

            for(int i = 0; i < Report.ReferencedAssemblies.Length; i++)
            {
                AddPlugin(GetFullAssemblyReference(Report.ReferencedAssemblies[i], ""));
            }

            tbPassword.Text = Report.Password;
            tbRetypePassword.Text = tbPassword.Text;

            if (Report.IsAncestor)
            {
                lblInheritance.Text = Res.Get("Forms,ReportOptions,Inherited") + "\r\n" + Report.BaseReport;
            }
            else
            {
                lblInheritance.Text = Res.Get("Forms,ReportOptions,NotInherited");
                rbDetach.Enabled = false;
            }

            tbRecipients.Text = Report.EmailSettings.RecipientsText;
            tbSubject.Text = Report.EmailSettings.Subject;
            tbMessage.Text = Report.EmailSettings.Message;
        }

        private bool Done()
        {
            if (DialogResult == DialogResult.OK)
            {
                if (tbPassword.Text != tbRetypePassword.Text)
                {
                    FRMessageBox.Error(Res.Get("Forms,ReportOptions,PasswordError"));
                    pcPages.ActivePage = pnSecurity;
                    tbRetypePassword.Focus();
                    return false;
                }

                Report.DoublePass = cbDoublePass.Checked;
                Report.Compressed = cbCompress.Checked;
                Report.UseFileCache = cbUseFileCache.Checked;
                Report.ConvertNulls = cbConvertNulls.Checked;
                Report.TextQuality = (TextQuality)cbxTextQuality.SelectedIndex;
                Report.SmoothGraphics = cbSmoothGraphics.Checked;

                Report.ReportInfo.Name = tbName.Text;
                Report.ReportInfo.Author = tbAuthor.Text;
                Report.ReportInfo.Version = tbVersion.Text;
                Report.ReportInfo.Description = tbDescription.Text;
                Report.ReportInfo.Picture = pbPicture.Image;
                Report.ReportInfo.SavePreviewPicture = cbSavePreviewPicture.Checked;

                Report.ScriptLanguage = rbC.Checked ? Language.CSharp : Language.Vb;
               

                List<string> assemlies = new List<string>();
                for (int i = 0; i < dgRefAssemblies.Rows.Count; i++)
                {
                    assemlies.Add((string)dgRefAssemblies.Rows[i].Cells[0].Value);
                }

                Report.ReferencedAssemblies = assemlies.ToArray();
                Report.Password = tbPassword.Text;

                if (rbDetach.Checked)
                {
                    Report.BaseReport = "";
                }
                else if (rbInherit.Checked && !String.IsNullOrEmpty(lblBaseName.Text.Trim()))
                {
                    Report.BaseReport = lblBaseName.Text;
                }

                Report.EmailSettings.RecipientsText = tbRecipients.Text;
                Report.EmailSettings.Subject = tbSubject.Text;
                Report.EmailSettings.Message = tbMessage.Text;
            }
            return true;
        }

        public override void Localize()
        {
            base.Localize();
            MyRes res = new MyRes("Forms,ReportOptions");
            Text = res.Get("");

            pnGeneral.Text = res.Get("General");
            pnDescription.Text = res.Get("Description");
            pnScript.Text = res.Get("Script");
            pnSecurity.Text = res.Get("Security");
            pnInheritance.Text = res.Get("Inheritance");
            pnEmail.Text = res.Get("Email");

            cbDoublePass.Text = res.Get("DoublePass");
            cbCompress.Text = res.Get("Compress");
            cbUseFileCache.Text = res.Get("UseFileCache");
            cbConvertNulls.Text = res.Get("ConvertNulls");
            lblTextQuality.Text = res.Get("TextQuality");
            cbxTextQuality.Items.AddRange(new string[] {
        res.Get("QualityDefault"), res.Get("QualityRegular"),
        res.Get("QualityClearType"), res.Get("QualityAntiAlias"),
        res.Get("QualitySingleBPP"), res.Get("QualitySingleBPPGridFit")});
            cbSmoothGraphics.Text = res.Get("SmoothGraphics");

            lblName.Text = res.Get("Name");
            lblAuthor.Text = res.Get("Author");
            lblDescription.Text = res.Get("Description1");
            lblVersion.Text = res.Get("Version");
            lblPicture.Text = res.Get("Picture");
            btnLoad.Text = res.Get("Load");
            btnClear.Text = res.Get("Clear");
            cbSavePreviewPicture.Text = res.Get("SavePreviewPicture");
            lblCreated.Text = res.Get("Created");
            lblModified.Text = res.Get("Modified");

            lblLanguage.Text = res.Get("Language");
            lblScriptNote.Text = res.Get("Note");
            lblRefAssemblies.Text = res.Get("RefAssemblies");
            btnAdd.Text = res.Get("Add");
            btnRemove.Text = res.Get("Remove");

            lblPassword.Text = res.Get("Password");
            lblRetypePassword.Text = res.Get("RetypePassword");

            lblChooseInheritance.Text = res.Get("Choose");
            rbDontChange.Text = res.Get("DontChange");
            rbDetach.Text = res.Get("Detach");
            rbInherit.Text = res.Get("Inherit");
            btnBrowse.Text = res.Get("Browse");

            lblRecipients.Text = res.Get("Recipients");
            lblSubject.Text = res.Get("Subject");
            lblMessage.Text = res.Get("Message");
        }

        public override void UpdateDpiDependencies()
        {
            base.UpdateDpiDependencies();
            lblInheritance.Width = lblInheritance.Parent.Width - 18;
            //tbDescription.Height = btnLoad.Top - tbDescription.Top - 14;
            dgRefAssemblies.Height = btnAdd.Top - dgRefAssemblies.Top - 12;
            tbRecipients.Height = lblSubject.Top - tbRecipients.Top - 8;
            tbMessage.Height = pnEmail.Height - tbMessage.Top - 16;
            tbDescription.Image = GetImage(68);
        }

        public ReportOptionsForm(Report report)
        {
            this.report = report;
            InitializeComponent();
            Localize();
            Init();
            UIUtils.CheckRTL(this);
            UpdateDpiDependencies();
        }
    }
}
