using System;
using System.IO;
using System.Xml;
using System.Drawing;
using System.Windows.Forms;
using FastReport.Table;
using FastReport.Utils;
#if MSCHART
using FastReport.MSChart;
using FastReport.DataVisualization.Charting;
#endif
using FastReport.Dialog;

namespace FastReport.Import.StimulSoft
{
    /// <summary>
    /// Represents the StimulSoft import plugin.
    /// </summary>
    public partial class StimulSoftImport : ImportBase
    {
        partial void LoadSVGImage(ReportComponentBase parent, XmlNode xmlObject, bool useAbsTop)
        {
            var SVGObject = ComponentsFactory.CreateSVGObject(xmlObject["Name"].InnerText, parent);
            LoadReportComponentBase(SVGObject, xmlObject);

            if (parent is TableCell)
            {
                RectangleF rect = ParseRectangleF(xmlObject["ClientRectangle"].InnerText);
                rect.Offset(-rect.Left, -rect.Top);
                rect.Offset(-rect.Left + 1, -rect.Top + 1);
                rect.Width -= 2;
                rect.Height -= 2;
                SVGObject.Bounds = rect;
            }
            else if (useAbsTop)
                SetAbsTop(SVGObject, parent);

            if (xmlObject["Margins"] != null)
                SVGObject.Padding = ParseMargins(xmlObject["Margins"].InnerText);

            if (xmlObject["File"] != null)
                SVGObject.ImageLocation = xmlObject["File"].InnerText;
            else if (xmlObject["ImageURL"] != null)
                SVGObject.ImageLocation = xmlObject["ImageURL"].InnerText;
        }

        partial void LoadRichText(ReportComponentBase band, XmlNode xmlObject, bool useAbsTop)
        {
            RichObject RichObject = ComponentsFactory.CreateRichObject(xmlObject["Name"].InnerText, band);
            LoadReportComponentBase(RichObject, xmlObject);

            if (band is TableCell)
            {
                RectangleF rect = ParseRectangleF(xmlObject["ClientRectangle"].InnerText);
                rect.Offset(-rect.Left + 1, -rect.Top + 1);
                rect.Width -= 2;
                rect.Height -= 2;
                RichObject.Bounds = rect;
            }
            else if (useAbsTop)
                SetAbsTop(RichObject, band);

            if (xmlObject["Margins"] != null)
                RichObject.Padding = ParseMargins(xmlObject["Margins"].InnerText);

            if (xmlObject["Text"] != null)
                RichObject.Text = UnitsConverter.ConvertRTF(xmlObject["Text"].InnerText);

            if (xmlObject["FullConvertExpression"] != null)
                RichObject.ConvertRichText = UnitsConverter.ConvertBool(xmlObject["FullConvertExpression"].InnerText);
        }

        partial void LoadSparkLine(BandBase band, XmlNode xmlObject, bool useAbsTop)
        {
        #if MSCHART
            SparklineObject sparkline = ComponentsFactory.CreateSparklineObject(xmlObject["Name"].InnerText, band);
            LoadReportComponentBase(sparkline, xmlObject);

            if (useAbsTop)
                SetAbsTop(sparkline, band);

            if (xmlObject["ValueDataColumn"] != null)
                sparkline.DataSource = Report.GetDataSource(xmlObject["ValueDataColumn"].InnerText);
        #endif
        }

        partial void LoadChart(BandBase band, XmlNode xmlObject, bool useAbsTop)
        {
        #if MSCHART
            MSChartObject chart = ComponentsFactory.CreateMSChartObject(xmlObject["Name"].InnerText, band);
            LoadReportComponentBase(chart, xmlObject);

            if (useAbsTop)
                SetAbsTop(chart, band);

            if (xmlObject["DataSourceName"] != null)
                chart.DataSource = Report.GetDataSource(xmlObject["DataSourceName"].InnerText);

            Title title = new Title();
            chart.Chart.Titles.Add(title);

            if (xmlObject["Text"] != null)
                title.Text = xmlObject["Text"].InnerText;

            if (xmlObject["Font"] != null)
                title.Font = ParseFont(xmlObject["Font"].InnerText);

            ChartArea chartArea = new ChartArea("Default");
            chart.Chart.ChartAreas.Add(chartArea);
            chartArea.AxisX = new Axis();
            chartArea.AxisX.IsMarginVisible = false;
            chartArea.AxisY = new Axis();
            chartArea.AxisY.IsMarginVisible = false;
            chartArea.AxisX2 = new Axis();
            chartArea.AxisY2 = new Axis();
            chartArea.Area3DStyle.LightStyle = LightStyle.None;

            if (xmlObject["Area"] != null)
            {
                if (xmlObject["Area"]["Brush"] != null)
                    chartArea.BackColor = UnitsConverter.ConvertColor(xmlObject["Area"]["Brush"].InnerText);

                if (xmlObject["Area"]["XAxis"] != null)
                    LoadAxis(chartArea.AxisX, xmlObject["Area"]["XAxis"]);

                if (xmlObject["Area"]["YAxis"] != null)
                    LoadAxis(chartArea.AxisY, xmlObject["Area"]["YAxis"]);

                if (xmlObject["Area"]["YRightAxis"] != null)
                    LoadAxis(chartArea.AxisY2, xmlObject["Area"]["YRightAxis"]);

                if (xmlObject["Area"]["XTopAxis"] != null)
                    LoadAxis(chartArea.AxisX2, xmlObject["Area"]["XTopAxis"]);
            }

            Legend legend = new Legend();
            chart.Chart.Legends.Add(legend);
            legend.IsDockedInsideChartArea = true;
            legend.LegendStyle = LegendStyle.Column;
            if (xmlObject["Legend"] != null)
            {
                if (xmlObject["Legend"]["Visible"] != null)
                    legend.Enabled = UnitsConverter.ConvertBool(xmlObject["Legend"]["Visible"].InnerText);

                if (xmlObject["Legend"]["Brush"] != null)
                    legend.BackColor = UnitsConverter.ConvertColor(xmlObject["Legend"]["Brush"].InnerText);

                if (xmlObject["Legend"]["Font"] != null)
                    legend.Font = ParseFont(xmlObject["Legend"]["Font"].InnerText);

                if (xmlObject["Legend"]["Title"] != null)
                    legend.Title = xmlObject["Legend"]["Title"].InnerText;

                if (xmlObject["Legend"]["TitleFont"] != null)
                    legend.TitleFont = ParseFont(xmlObject["Legend"]["TitleFont"].InnerText);

                if (xmlObject["Legend"]["BorderColor"] != null)
                    legend.BorderColor = UnitsConverter.ConvertColor(xmlObject["Legend"]["BorderColor"].InnerText);
            }

            foreach (XmlNode series in xmlObject["Series"])
            {
                MSChartSeries msSeries = chart.AddSeries(UnitsConverter.ConvertChartType(series.Attributes["type"].Value));
                if (series["ToolTipDataColumn"] != null)
                    msSeries.SeriesSettings.ToolTip = series["ToolTipDataColumn"].InnerText;

                if (series["Title"] != null)
                    msSeries.Name = series["Title"].InnerText;

                if (series["Brush"] != null)
                    msSeries.SeriesSettings.Color = UnitsConverter.ConvertBrushToColor(UnitsConverter.ConvertBrush(series["Brush"].InnerText));

                if (series["ListOfArguments"] != null && series["ListOfValues"] != null)
                {
                    string[] ListValue = series["ListOfValues"].InnerText.Split(';');
                    string[] ListArgument = series["ListOfArguments"].InnerText.Split(';');
                    for (int i = 0; i < ListArgument.Length; i++)
                    {
                        if (ListValue.Length != ListArgument.Length && ListValue.Length <= i)
                            msSeries.AddValue(ListArgument[i], 0);
                        else
                            msSeries.AddValue(ListArgument[i], ListValue[i]);
                    }
                }

                if (series["ValueDataColumn"] != null)
                    msSeries.XValue = SwapBarackets(series["ValueDataColumn"].InnerText);

                if (series["ArgumentDataColumn"] != null)
                    msSeries.YValue1 = SwapBarackets(series["ArgumentDataColumn"].InnerText);
            }
        #endif
        }

#if MSCHART
        private void LoadAxis(Axis axis, XmlNode node)
        {
            if (node["LineStyle"] != null)
                axis.LineDashStyle = UnitsConverter.ConvertBorderChartDashStyle(node["LineStyle"].InnerText);
            if (node["LineColor"] != null)
                axis.LineColor = UnitsConverter.ConvertColor(node["LineColor"].InnerText);
            if (node["Title"] != null)
            {
                if (node["Title"]["Font"] != null)
                    axis.TitleFont = ParseFont(node["Title"]["Font"].InnerText);
                if (node["Title"]["Color"] != null)
                    axis.TitleForeColor = UnitsConverter.ConvertColor(node["Title"]["Color"].InnerText);
            }
            if (node["Width"] != null)
                axis.LineWidth = UnitsConverter.ConvertInt(node["Width"].InnerText);
        }
#endif

#if !FRCORE
        partial void LoadDialogPage(XmlNode node)
        {
            DialogPage page = ComponentsFactory.CreateDialogPage(Report);
            page.Form.Width = UnitsConverter.ConvertSize(node["Size"].InnerText).Width;
            page.Form.Height = UnitsConverter.ConvertSize(node["Size"].InnerText).Height + 10;
            page.Text = node["Text"].InnerText;
            LoadDialogObjects(page, node);
            page.Form.Scale(new SizeF(DrawUtils.ScreenDpi / 96f, DrawUtils.ScreenDpi / 96f));
        }

        private void LoadDialogObjects(Base parent, XmlNode node)
        {
            foreach (XmlNode control in node["Components"])
            {
                switch (RemovePrefix(control.Attributes["type"].Value))
                {
                    case "TextBoxControl":
                        TextBoxControl textBox = ComponentsFactory.CreateTextBoxControl(control["Name"].InnerText, parent);
                        textBox.Multiline = true;
                        LoadSizeAndLocation(textBox, control);
                        break;

                    case "LabelControl":
                        LabelControl labelControl = ComponentsFactory.CreateLabelControl(control["Name"].InnerText, parent);
                        labelControl.AutoSize = false;
                        LoadSizeAndLocation(labelControl, control);
                        labelControl.Text = control["Text"].InnerText;

                        if (control["TextAlign"] != null)
                            labelControl.TextAlign = UnitsConverter.ConvertContentAlignment(control["TextAlign"].InnerText);
                        break;

                    case "RadioButtonControl":
                        RadioButtonControl radioButton = ComponentsFactory.CreateRadioButtonControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(radioButton, control);
                        radioButton.Text = control["Text"].InnerText;

                        if (control["Checked"] != null)
                            radioButton.Checked = UnitsConverter.ConvertBool(control["Checked"].InnerText);
                        break;

                    case "DateTimePickerControl":
                        DateTimePickerControl dateTimePickerControl = ComponentsFactory.CreateDateTimePickerControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(dateTimePickerControl, control);
                        break;

                    case "GridControl":
                        GridControl gridControl = ComponentsFactory.CreateGridControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(gridControl, control);

                        foreach (XmlNode column in control["Columns"])
                        {
                            GridControlColumn controlColumn = new GridControlColumn();

                            string[] parametrs = column.InnerText.Split(',');
                            controlColumn.DataColumn = parametrs[0];
                            controlColumn.Visible = UnitsConverter.ConvertBool(parametrs[1]);
                            controlColumn.Width = UnitsConverter.ConvertInt(parametrs[2]);

                            if (UnitsConverter.ConvertInt(parametrs[2]) == 0)
                                controlColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

                            controlColumn.HeaderText = parametrs[4];

                            gridControl.AddChild(controlColumn);
                        }
                        break;

                    case "GroupBoxControl":
                        GroupBoxControl groupBox = ComponentsFactory.CreateGroupBoxControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(groupBox, control);
                        LoadDialogObjects(groupBox, control);
                        groupBox.Text = control["Text"].InnerText;
                        break;

                    case "ButtonControl":
                        ButtonControl buttonControl = ComponentsFactory.CreateButtonControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(buttonControl, control);
                        buttonControl.Text = control["Text"].InnerText;

                        if (control["Image"] != null)
                        {
                            MemoryStream memoryStream = new MemoryStream();
                            StreamWriter streamWriter = new StreamWriter(memoryStream);
                            byte[] arrayimg = Convert.FromBase64String(control["Image"].InnerText);
                            buttonControl.Image = ImageHelper.Load(arrayimg);
                            streamWriter.Dispose();
                            memoryStream.Dispose();
                        }
                        break;

                    case "CheckBoxControl":
                        CheckBoxControl checkBoxControl = ComponentsFactory.CreateCheckBoxControl(control["Name"].InnerText, parent);

                        if (control["Checked"] != null)
                            checkBoxControl.Checked = UnitsConverter.ConvertBool(control["Checked"].InnerText);

                        LoadSizeAndLocation(checkBoxControl, control);
                        checkBoxControl.Text = control["Text"].InnerText;
                        break;

                    case "ListBoxControl":
                        ListBoxControl listBoxControl = ComponentsFactory.CreateListBoxControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(listBoxControl, control);
                        break;

                    case "CheckedListBoxControl":
                        CheckedListBoxControl checkedListBoxControl = ComponentsFactory.CreateCheckedListBoxControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(checkedListBoxControl, control);
                        break;

                    case "PanelControl":
                        PanelControl panelControl = ComponentsFactory.CreatePanelControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(panelControl, control);
                        LoadDialogObjects(panelControl, control);
                        break;

                    case "LookUpBoxControl":
                        ComboBoxControl comboBoxControl = ComponentsFactory.CreateComboBoxControl(control["Name"].InnerText, parent);
                        comboBoxControl.DropDownStyle = ComboBoxStyle.DropDownList;
                        LoadSizeAndLocation(comboBoxControl, control);
                        comboBoxControl.Text = control["Text"].InnerText;
                        break;

                    case "NumericUpDownControl":
                        NumericUpDownControl numericUpDownControl = ComponentsFactory.CreateNumericUpDownControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(numericUpDownControl, control);

                        if (control["Minimum"] != null)
                            numericUpDownControl.Minimum = (decimal)UnitsConverter.ConvertFloat(control["Minimum"].InnerText);

                        if (control["Maximum"] != null)
                            numericUpDownControl.Maximum = (decimal)UnitsConverter.ConvertFloat(control["Maximum"].InnerText);

                        if (control["Value"] != null)
                            numericUpDownControl.Value = (decimal)UnitsConverter.ConvertFloat(control["Value"].InnerText);
                        break;

                    case "PictureBoxControl":
                        PictureBoxControl pictureBoxControl = ComponentsFactory.CreatePictureBoxControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(pictureBoxControl, control);

                        pictureBoxControl.PictureBox.SizeMode = PictureBoxSizeMode.Zoom;
                        if (control["Image"] != null)
                        {
                            MemoryStream memoryStream = new MemoryStream();
                            StreamWriter streamWriter = new StreamWriter(memoryStream);
                            byte[] arrayimg = Convert.FromBase64String(control["Image"].InnerText);
                            pictureBoxControl.Image = ImageHelper.Load(arrayimg);
                            streamWriter.Dispose();
                            memoryStream.Dispose();
                        }
                        break;

                    case "ListViewControl":
                        ListViewControl listViewControl = ComponentsFactory.CreateListViewControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(listViewControl, control);
                        break;

                    case "RichTextBoxControl":
                        RichTextBoxControl richTextBoxControl = ComponentsFactory.CreateRichTextBoxControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(richTextBoxControl, control);
                        richTextBoxControl.RichTextBox.Rtf = UnitsConverter.ConvertRTF(control["Text"].InnerText);
                        break;

                    case "TreeViewControl":
                        TreeViewControl treeViewControl = ComponentsFactory.CreateTreeViewControl(control["Name"].InnerText, parent);
                        LoadSizeAndLocation(treeViewControl, control);
                        break;
                }
            }
        }

        private void LoadSizeAndLocation(DialogControl control, XmlNode node)
        {
            control.Size = UnitsConverter.ConvertSize(node["Size"].InnerText);
            control.Location = UnitsConverter.ConvertPoint(node["Location"].InnerText);
        }
#endif
        partial void LoadMap(ReportComponentBase band, XmlNode xmlObject, bool useAbsTop)
        {
            Map.MapObject map = ComponentsFactory.CreateMapObject(xmlObject["Name"].InnerText, band);
            LoadReportComponentBase(map, xmlObject);

            if (useAbsTop)
                SetAbsTop(map, band);
        }
    }
}