//----------------------------------------------------------------------------
// ReportStyleForm.cs
//
// Style form for C1ReportDesigner application
//
// This is a part of the C1ReportDesigner package.
// Copyright (C) ComponentOne LLC
// All rights reserved.
//
// This source code is intended as a supplement to the
// C1ReportDesigner control and related documentation 
// provided with the product.
// See these sources for detailed information regarding the
// C1ReportDesigner product.
//----------------------------------------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace ReportDesignerApp
{
	using C1.Win.C1ReportDesigner;
	using ReportDesignerApp.Util;

	/// <summary>
	/// Summary description for ReportStyleForm.
	/// </summary>
	public class ReportStyleForm : System.Windows.Forms.Form
	{
		private System.Windows.Forms.ListBox _list;
		private System.Windows.Forms.PictureBox _preview;
		private System.Windows.Forms.Button _btnOK;
		private System.Windows.Forms.Button _btnCancel;
		private System.Windows.Forms.Button _btnApply;
		private System.Windows.Forms.PropertyGrid _propGrid;
		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.Button _btnRemove;
		private System.Windows.Forms.Button _btnAdd;
        private Label label1;
        private ToolTip toolTip1;
        private Label _lblPropGrid;
        private IContainer components;

        MainForm _owner;

		public ReportStyleForm(MainForm owner)
		{
			InitializeComponent();
            AutoScaleMode = AutoScaleMode.None;
            Font = MainForm.DefaultAppFont;
            _owner = owner;
        }

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            this._list = new System.Windows.Forms.ListBox();
            this._preview = new System.Windows.Forms.PictureBox();
            this._btnOK = new System.Windows.Forms.Button();
            this._btnCancel = new System.Windows.Forms.Button();
            this._btnApply = new System.Windows.Forms.Button();
            this._propGrid = new System.Windows.Forms.PropertyGrid();
            this._btnRemove = new System.Windows.Forms.Button();
            this._btnAdd = new System.Windows.Forms.Button();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.label1 = new System.Windows.Forms.Label();
            this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
            this._lblPropGrid = new System.Windows.Forms.Label();
            ((System.ComponentModel.ISupportInitialize)(this._preview)).BeginInit();
            this.SuspendLayout();
            // 
            // _list
            // 
            this._list.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)));
            this._list.IntegralHeight = false;
            this._list.Location = new System.Drawing.Point(10, 24);
            this._list.Name = "_list";
            this._list.Size = new System.Drawing.Size(184, 308);
            this._list.TabIndex = 1;
            this._list.SelectedIndexChanged += new System.EventHandler(this._list_SelectedIndexChanged);
            this._list.DoubleClick += new System.EventHandler(this._list_DoubleClick);
            // 
            // _preview
            // 
            this._preview.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this._preview.BackColor = System.Drawing.SystemColors.AppWorkspace;
            this._preview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this._preview.Location = new System.Drawing.Point(200, 162);
            this._preview.Name = "_preview";
            this._preview.Size = new System.Drawing.Size(254, 200);
            this._preview.TabIndex = 1;
            this._preview.TabStop = false;
            // 
            // _btnOK
            // 
            this._btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this._btnOK.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this._btnOK.Location = new System.Drawing.Point(256, 378);
            this._btnOK.Name = "_btnOK";
            this._btnOK.Size = new System.Drawing.Size(95, 28);
            this._btnOK.TabIndex = 8;
            this._btnOK.Text = "&OK";
            this._btnOK.Click += new System.EventHandler(this._btnOK_Click);
            // 
            // _btnCancel
            // 
            this._btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this._btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this._btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this._btnCancel.Location = new System.Drawing.Point(357, 378);
            this._btnCancel.Name = "_btnCancel";
            this._btnCancel.Size = new System.Drawing.Size(95, 28);
            this._btnCancel.TabIndex = 9;
            this._btnCancel.Text = "&Cancel";
            this._btnCancel.Click += new System.EventHandler(this._btnCancel_Click);
            // 
            // _btnApply
            // 
            this._btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this._btnApply.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this._btnApply.Location = new System.Drawing.Point(10, 378);
            this._btnApply.Name = "_btnApply";
            this._btnApply.Size = new System.Drawing.Size(90, 28);
            this._btnApply.TabIndex = 10;
            this._btnApply.Text = "Appl&y";
            this.toolTip1.SetToolTip(this._btnApply, "Apply selected style to the report");
            this._btnApply.Click += new System.EventHandler(this._btnApply_Click);
            // 
            // _propGrid
            // 
            this._propGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this._propGrid.HelpVisible = false;
            this._propGrid.LineColor = System.Drawing.SystemColors.ScrollBar;
            this._propGrid.Location = new System.Drawing.Point(200, 24);
            this._propGrid.Name = "_propGrid";
            this._propGrid.PropertySort = System.Windows.Forms.PropertySort.Alphabetical;
            this._propGrid.Size = new System.Drawing.Size(254, 132);
            this._propGrid.TabIndex = 5;
            this._propGrid.ToolbarVisible = false;
            this._propGrid.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this._propGrid_PropertyValueChanged);
            // 
            // _btnRemove
            // 
            this._btnRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this._btnRemove.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this._btnRemove.Location = new System.Drawing.Point(104, 338);
            this._btnRemove.Name = "_btnRemove";
            this._btnRemove.Size = new System.Drawing.Size(90, 28);
            this._btnRemove.TabIndex = 3;
            this._btnRemove.Text = "&Remove";
            this.toolTip1.SetToolTip(this._btnRemove, "Remove custom style.");
            this._btnRemove.Click += new System.EventHandler(this._btnRemove_Click);
            // 
            // _btnAdd
            // 
            this._btnAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this._btnAdd.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this._btnAdd.Location = new System.Drawing.Point(10, 338);
            this._btnAdd.Name = "_btnAdd";
            this._btnAdd.Size = new System.Drawing.Size(90, 28);
            this._btnAdd.TabIndex = 2;
            this._btnAdd.Text = "&Add";
            this.toolTip1.SetToolTip(this._btnAdd, "Add a custom style based on the current selection");
            this._btnAdd.Click += new System.EventHandler(this._btnAdd_Click);
            // 
            // groupBox1
            // 
            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox1.Location = new System.Drawing.Point(8, 372);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(446, 2);
            this.groupBox1.TabIndex = 7;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "groupBox1";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(7, 8);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(68, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Style Gallery:";
            // 
            // _lblPropGrid
            // 
            this._lblPropGrid.AutoSize = true;
            this._lblPropGrid.Location = new System.Drawing.Point(197, 9);
            this._lblPropGrid.Name = "_lblPropGrid";
            this._lblPropGrid.Size = new System.Drawing.Size(54, 13);
            this._lblPropGrid.TabIndex = 4;
            this._lblPropGrid.Text = "Edit Style:";
            // 
            // ReportStyleForm
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.CancelButton = this._btnCancel;
            this.ClientSize = new System.Drawing.Size(464, 409);
            this.Controls.Add(this._lblPropGrid);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this._btnOK);
            this.Controls.Add(this._preview);
            this.Controls.Add(this._list);
            this.Controls.Add(this._btnCancel);
            this.Controls.Add(this._btnApply);
            this.Controls.Add(this._btnRemove);
            this.Controls.Add(this._btnAdd);
            this.Controls.Add(this._propGrid);
            this.MinimumSize = new System.Drawing.Size(480, 445);
            this.Name = "ReportStyleForm";
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Report Style Editor";
            this.Load += new System.EventHandler(this.ReportStyleForm_Load);
            ((System.ComponentModel.ISupportInitialize)(this._preview)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion

		// object model
		private C1ReportDesigner _designer;
		public C1ReportDesigner Designer
		{
			get { return _designer; }
			set { _designer = value; }
		}
		private bool _dirty = false;

		// populate style list on start-up
		private void ReportStyleForm_Load(object sender, System.EventArgs e)
		{
            foreach (ReportStyle style in ReportStyle.StyleList)
            {
                _list.Items.Add(style);
                if (string.Compare(style.Name, _owner._defaultStyleName, true) == 0)
                {
                    _list.SelectedIndex = _list.Items.Count - 1;
                }
            }
            if (_list.SelectedIndex < 0)
            {
                _list.SelectedIndex = 0;
            }
			_dirty = false;
		}

		// update style preview
		private void _list_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			// get current style
			ReportStyle style = _list.SelectedItem as ReportStyle;
			if (style == null) return;

			// update preview
			_preview.Image = style.GetPreview(false);

			// update property grid
			_propGrid.SelectedObject = style;
			_propGrid.Enabled = style.IsCustom;
			_propGrid.Refresh();

            // only custom styles can be edited
            _lblPropGrid.Text = style.IsCustom
                ? "Edit Custom Style:"
                : "Built-In Style (not editable)";

			// update buttons
			_btnRemove.Enabled = style.IsCustom;
		}

        // apply style when user double-clicks it on the list
        private void _list_DoubleClick(object sender, EventArgs e)
        {
            _btnApply_Click(this, e);
        }

		// update preview when properties change
		private void _propGrid_PropertyValueChanged(object s, System.Windows.Forms.PropertyValueChangedEventArgs e)
		{
			// update preview
			ReportStyle style = _list.SelectedItem as ReportStyle;
			_preview.Image = style.GetPreview(true);

			// update list
			if (e.ChangedItem.PropertyDescriptor.Name == "Name")
			{
				int index = _list.SelectedIndex;
				_list.Items[index] = style;
			}

			// remember we're dirty
			_dirty = true;
		}

		// handle buttons
		private void _btnOK_Click(object sender, System.EventArgs e)
		{
			// apply current style
			_btnApply_Click(sender, e);

			// save any changes to settings file
			if (_dirty)
			{
				string msg = "Do you want to save the style definition changes?";
				DialogResult dr = MessageBox.Show(msg, "Save Changes", MessageBoxButtons.YesNoCancel);
				switch (dr)
				{
					// cancel and keep dialog open
					case DialogResult.Cancel:
						return;

					// save all custom styles into app settings file
					case DialogResult.Yes:

						// build new custom style list
						ArrayList al = new ArrayList();
						foreach (ReportStyle s in _list.Items)
							if (s.IsCustom) al.Add(s.StyleDefinition);

						// save new list
						AppSettings.SaveList("customstyles", al, false);

						// done
						break;
				}
			}

			// done with dialog
			DialogResult = DialogResult.OK;
		}
		private void _btnCancel_Click(object sender, System.EventArgs e)
		{
			DialogResult = DialogResult.Cancel;
		}
		private void _btnApply_Click(object sender, System.EventArgs e)
		{
			// get selected style
			ReportStyle style = _list.SelectedItem as ReportStyle;
			if (style != null && _designer != null && _designer.Report != null)
			{
				// save state, apply to report, repaint
				_designer.UndoStack.SaveState();
				style.Apply(_designer.Report);
				_designer.Invalidate();

                // this is the new 'current' style
                _owner._defaultStyleName = style.Name;
			}
		}
        private void _btnAdd_Click(object sender, System.EventArgs e)
		{
			// clone current style
			ReportStyle style = _list.SelectedItem as ReportStyle;
			ReportStyle clone = style.Clone() as ReportStyle;

			// ensure that new name is unique
			clone.Name = CreateUniqueName(clone.Name);

			// add it to list control
			_list.Items.Add(clone);
			_list.SelectedItem = clone;

			// remember we're dirty
			_dirty = true;
		}
		private string CreateUniqueName(string name)
		{
			// already unique? no work
			if (!ListContains(name))
				return name;

			// make sure we have some kind of name
			if (name == null || name.Length == 0)
				name = "New Style";

			// strip trailing digits
			string baseName = Regex.Replace(name, "(.+) [0-9]+$", "$1");

			// and append counter until unique
			for (int i = 1;; i++)
			{
				string newName = string.Format("{0} {1}", baseName, i);
				if (!ListContains(newName))
				{
					return newName;
				}
			}
		}
		private bool ListContains(string name)
		{
			foreach (ReportStyle s in _list.Items)
			{
				if (string.Compare(s.Name, name, true) == 0)
					return true;
			}
			return false;
		}
		private void _btnRemove_Click(object sender, System.EventArgs e)
		{
			// get current style, index
			ReportStyle style = _list.SelectedItem as ReportStyle;
			int index = _list.SelectedIndex;

			// remove current style
			_list.Items.Remove(style);

			// restore index
			if (index >= _list.Items.Count)
				index = _list.Items.Count - 1;
			_list.SelectedIndex = index;

			// remember we're dirty
			_dirty = true;
		}
	}
}
