using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using Volpe.Cafe;
using Volpe.Cafe.Model;
namespace Volpe.Cafe.UI.Panels
{
	public class CompliancePanel : CafeUserControl
	{
        #region 
		public CompliancePanel()
		{
			this.InitializeComponent();
            this.PostInitialize();
        }
		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
		}
        #endregion
        #region 
		#region 
        void InitializeComponent()
		{
            System.Windows.Forms.Label label1;
            System.Windows.Forms.Label label2;
            this.ux_complianceLabel = new System.Windows.Forms.Label();
            this.ux_compliancePanel = new System.Windows.Forms.Panel();
            this.ux_userNotesPanel = new System.Windows.Forms.Panel();
            this.ux_userKeywords = new System.Windows.Forms.TextBox();
            this.ux_userNotes = new System.Windows.Forms.TextBox();
            this.ux_userNotesLabel = new System.Windows.Forms.Label();
            label1 = new System.Windows.Forms.Label();
            label2 = new System.Windows.Forms.Label();
            this.ux_userNotesPanel.SuspendLayout();
            this.SuspendLayout();
            label1.AutoSize = true;
            label1.Location = new System.Drawing.Point(8, 8);
            label1.Name = "label1";
            label1.Size = new System.Drawing.Size(38, 13);
            label1.TabIndex = 0;
            label1.Text = "Notes:";
            label2.AutoSize = true;
            label2.Location = new System.Drawing.Point(8, 56);
            label2.Name = "label2";
            label2.Size = new System.Drawing.Size(56, 13);
            label2.TabIndex = 2;
            label2.Text = "Keywords:";
            this.ux_complianceLabel.AutoSize = true;
            this.ux_complianceLabel.Location = new System.Drawing.Point(8, 8);
            this.ux_complianceLabel.Name = "ux_complianceLabel";
            this.ux_complianceLabel.Size = new System.Drawing.Size(205, 13);
            this.ux_complianceLabel.TabIndex = 0;
            this.ux_complianceLabel.Text = "What type of model would you like to run?";
            this.ux_compliancePanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_compliancePanel.Location = new System.Drawing.Point(8, 16);
            this.ux_compliancePanel.Name = "ux_compliancePanel";
            this.ux_compliancePanel.Size = new System.Drawing.Size(424, 48);
            this.ux_compliancePanel.TabIndex = 1;
            this.ux_userNotesPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_userNotesPanel.Controls.Add(this.ux_userKeywords);
            this.ux_userNotesPanel.Controls.Add(label2);
            this.ux_userNotesPanel.Controls.Add(this.ux_userNotes);
            this.ux_userNotesPanel.Controls.Add(label1);
            this.ux_userNotesPanel.Location = new System.Drawing.Point(8, 80);
            this.ux_userNotesPanel.Name = "ux_userNotesPanel";
            this.ux_userNotesPanel.Size = new System.Drawing.Size(424, 80);
            this.ux_userNotesPanel.TabIndex = 3;
            this.ux_userKeywords.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_userKeywords.Location = new System.Drawing.Point(64, 56);
            this.ux_userKeywords.Name = "ux_userKeywords";
            this.ux_userKeywords.Size = new System.Drawing.Size(352, 20);
            this.ux_userKeywords.TabIndex = 3;
            this.ux_userNotes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_userNotes.Location = new System.Drawing.Point(48, 8);
            this.ux_userNotes.Multiline = true;
            this.ux_userNotes.Name = "ux_userNotes";
            this.ux_userNotes.Size = new System.Drawing.Size(368, 44);
            this.ux_userNotes.TabIndex = 1;
            this.ux_userNotesLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.ux_userNotesLabel.Location = new System.Drawing.Point(8, 72);
            this.ux_userNotesLabel.Name = "ux_userNotesLabel";
            this.ux_userNotesLabel.Size = new System.Drawing.Size(424, 13);
            this.ux_userNotesLabel.TabIndex = 2;
            this.ux_userNotesLabel.Text = "Optionally, please specify additional notes and/or keywords describing the type o" +
                "f run:";
            this.Controls.Add(this.ux_userNotesLabel);
            this.Controls.Add(this.ux_userNotesPanel);
            this.Controls.Add(this.ux_complianceLabel);
            this.Controls.Add(this.ux_compliancePanel);
            this.MinimumSize = new System.Drawing.Size(440, 0);
            this.Name = "CompliancePanel";
            this.Size = new System.Drawing.Size(440, 179);
            this.ux_userNotesPanel.ResumeLayout(false);
            this.ux_userNotesPanel.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();
        }
		#endregion
        SizeF MeasureString(Graphics g, string text, Font font, int width)
        {
            SizeF fontSize = g.MeasureString(text, font);
            float fontH    = g.MeasureString("a", font).Height;
            int startLineCount = (int)Math.Ceiling(fontSize.Height / fontH);
            int lineCount = (int)Math.Ceiling(fontSize.Width / width);
            return new SizeF(width, fontH * (lineCount + startLineCount - 1) + 2);
        }
        void PostInitialize()
        {
            this.RegisterTextControl(this.ux_userNotes, string.Empty, null, null, true);
            this.RegisterTextControl(this.ux_userKeywords, string.Empty, null, null, true);
            this.AutoInitializeCheckChangesDetector(this.Controls);
        }
        void InitializeComplianceList(Type[] complianceTypes, ICompliance initialCompliance)
        {
            const string errMessage = "At least one compliance model must be specified in the complianceTypes array.";
            if (complianceTypes == null) { throw new ArgumentNullException("complianceTypes", errMessage); }
            if (complianceTypes.Length < 1) { throw new ArgumentException(errMessage, "complianceTypes"); }
            int      y     = 8;                                         
            Graphics g     = this.ux_compliancePanel.CreateGraphics();
            Font     font  = this.ux_compliancePanel.Font;
            int      width = this.ux_compliancePanel.Width - 24;        
            string initialComplianceName = (initialCompliance == null) ? "volpe.cafe.model.compliance" :
                initialCompliance.GetType().FullName.ToLower();
            for (int i = 0; i < complianceTypes.Length; i++)
            {
                Type            item       = complianceTypes[i];
                ConstructorInfo ctor       = item.GetConstructor(Type.EmptyTypes);
                ICompliance     compliance = (ICompliance)ctor.Invoke(new object[] {});
                ModelDescriptionAttribute attr = (ModelDescriptionAttribute)Attribute.GetCustomAttribute(item, typeof(ModelDescriptionAttribute));
                string name  = attr.FullTitle;
                string descr = attr.Description;
                string text  = name + "\n" + descr;
                SizeF  size  = this.MeasureString(g, text, font, width - 16);
                RadioButton rdb = new RadioButton();
                rdb.CheckAlign  = ContentAlignment.TopLeft;
                rdb.FlatStyle   = FlatStyle.Popup;
                rdb.Location    = new Point(8, y);
                rdb.Size        = new Size(width, (int)(size.Height + 1));
                rdb.Tag         = compliance;
                rdb.Text        = text;
                rdb.TextAlign   = ContentAlignment.TopLeft;
                rdb.CheckedChanged += new EventHandler(this.CheckChangesDetector);
                rdb.CheckedChanged += new EventHandler(this.ComplianceItem_CheckedChanged);
                this.ux_compliancePanel.Controls.Add(rdb);
                y = rdb.Top + rdb.Height + 8;
                if (initialComplianceName == item.FullName.ToLower()) { rdb.Checked = true; }
            }
            if (initialCompliance != null)
            {
                this.ux_userNotes   .Text = initialCompliance.UserNotes;
                this.ux_userKeywords.Text = initialCompliance.UserKeywords;
            }
            this.ux_compliancePanel.Height = y;
            this.ux_userNotesLabel.Top = this.ux_compliancePanel.Height + this.ux_compliancePanel.Top + 8;
            this.ux_userNotesPanel.Top = this.ux_userNotesLabel.Top + 8;
        }
        void ComplianceItem_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton rdb = (RadioButton)sender;
            if (rdb.Checked)
            {
                this._selCompliance = (ICompliance)rdb.Tag;
            }
        }
        public void SetInitialState(Type[] complianceTypes, ICompliance compliance)
        {
            this.InitializeComplianceList(complianceTypes, compliance);
            if (compliance != null) { this.SaveChanges(); }
        }
        public override void SaveChanges()
        {
            if (this.SettingsChanged)
            {
                this._compliance              = this._selCompliance.CreateNew();
                this._compliance.UserNotes    = this.ux_userNotes.Text;
                this._compliance.UserKeywords = this.ux_userKeywords.Text;
                base.SaveChanges();
            }
        }
        #endregion
        #region 
        [Browsable(false)]
        public override bool SettingsChanged { get { return base.SettingsChanged || (this._compliance == null); } }
        [Browsable(false)]
        public ICompliance Compliance { get { return this._compliance; } }
        [Browsable(false)]
        public ICompliance SelectedCompliance { get { return this._selCompliance; } }
        #endregion
        #region 
        #region 
        Label   ux_complianceLabel;
        Panel   ux_compliancePanel;
        Label   ux_userNotesLabel;
        Panel   ux_userNotesPanel;
        TextBox ux_userNotes;
        TextBox ux_userKeywords;
        #endregion
        ICompliance _compliance;
        ICompliance _selCompliance;
        #endregion
    }
}

