//----------------------------------------------------------------------------
// FieldPicker.cs
//
// FieldPicker inherits from the ComboBox control and connects with a 
// ReportDesigner control to provide a list of report sections and fields
// that is synchronized with the selection (changes in the designer affect
// the Picker and vice-versa).
//
// This is a part of the C1ReportDesigner package.
// Copyright (C) GrapeCity, Inc
// 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.Windows.Forms;

using C1.C1Report;
using C1.Win.C1ReportDesigner;

namespace ReportDesignerApp.Util
{
	/// <summary>
    /// FieldPicker inherits from the ComboBox control and connects with a 
    /// ReportDesigner control to provide a list of report sections and fields
    /// that is synchronized with the selection (changes in the designer affect
    /// the Picker and vice-versa).
	/// </summary>
	public class FieldPicker : ComboBox
	{
		private C1ReportDesigner _designer;

        #region Constructors

        public FieldPicker()
		{
			DrawMode      = DrawMode.OwnerDrawFixed;
			DropDownStyle = ComboBoxStyle.DropDownList;
        }

        #endregion

        #region Public properties

        public C1ReportDesigner Designer
        {
            get { return _designer; }
            set
            {
                // unhook previous event handlers
                if (_designer != null)
                {
                    _designer.VisibleChanged -= new EventHandler(_designer_VisibleChanged);
                    _designer.SelectionChanged -= new EventHandler(_designer_SelectionChanged);
                    _designer.ReportChanged -= new EventHandler(_designer_ReportChanged);
                }

                // set value
                _designer = value;

                // hook event handers
                if (_designer != null)
                {
                    _designer.VisibleChanged += new EventHandler(_designer_VisibleChanged);
                    _designer.SelectionChanged += new EventHandler(_designer_SelectionChanged);
                    _designer.ReportChanged += new EventHandler(_designer_ReportChanged);
                }
            }
        }

        public new object SelectedItem
		{
			get { return base.SelectedItem; }
			set
			{
				// refill list if the item is not in it
				if (value != null && !Items.Contains(value))
					FillList();

				// base processing
				base.SelectedItem = value;

			}
        }

        #endregion

        #region Private

        private void FillList()
        {
            // save selection
            object selected = SelectedItem;

            // clear list
            Items.Clear();
            if (_designer == null || _designer.Report == null)
                return;

            // populate list
            Items.Add(_designer.Report);
            foreach (Section s in _designer.Report.Sections)
            {
                Items.Add(s);
                foreach (Field f in s.Fields)
                    Items.Add(f);
            }

            // restore selection
            if (selected != null && Items.Contains(selected))
                SelectedItem = selected;
        }

        private void _designer_VisibleChanged(object sender, EventArgs e)
		{
			// enable and update selection when designer is visible
			if (_designer.Visible)
			{
				Enabled = true;
				_designer_SelectionChanged(null, EventArgs.Empty);
			}
			else // disable and select report when designer is invisible
			{
				Enabled = false;
				SelectedItem = _designer.Report;
			}
		}

		private void _designer_SelectionChanged(object sender, EventArgs e)
		{
			object[] sel = _designer.SelectedFields;
			
			// show field properties
			if (sel.Length > 0)								
				SelectedItem = (sel.Length == 1)? sel[0]: null;

			// show section properties
			else if (_designer.SelectedSection != null)
				SelectedItem = _designer.SelectedSection;

			// show report properties
			else if (_designer.Report != null) 
				SelectedItem = _designer.Report;

			// nothing to show...
			else 
				SelectedItem = null;
		}

		private void _designer_ReportChanged(object sender, EventArgs e)
		{
			FillList();
        }

        #endregion

        #region Protected

        protected override void OnSelectionChangeCommitted(EventArgs e)
		{
			// synchronize designer selection with list selection
			if (_designer != null)
			{
				C1Report r = SelectedItem as C1Report;
				if (r != null)
				{
					_designer.SelectedFields = null;
					_designer.SelectedSection = null;
				}
				Section s = SelectedItem as Section;
				if (s != null)
				{
					_designer.SelectedFields = null;
					_designer.SelectedSection = s;
				}
				Field f = SelectedItem as Field;
				if (f != null)
				{
					Field[] sel = { f };
					_designer.SelectedSection = _designer.Report.Sections[f.Section];
					_designer.SelectedFields = sel;
				}

				// done, send focus back to designer
				_designer.Focus();
			}

			// allow base class processing
			base.OnSelectionChangeCommitted(e);
		}

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            // initialize objects
            string text = string.Empty;
            Brush brush = SystemBrushes.WindowText;
            Brush backBrush = SystemBrushes.Window;

            // get selected item, set bold font for sections
            object item = (e.Index < 0) ? SelectedItem : Items[e.Index];
            C1Report r = item as C1Report;
            if (r != null)
            {
                text = r.ReportName;
                if (text == null || text.Length == 0)
                    text = Strings.FieldPicker.UnnamedReport;
            }
            Section s = item as Section;
            if (s != null)
            {
                text = s.Name;
                if (text == null || text.Length == 0)
                    text = Strings.FieldPicker.UnnamedSection;
                text = "  " + text;
                backBrush = SystemBrushes.ControlLight;
            }
            Field f = item as Field;
            if (f != null)
            {
                text = f.Name;
                if (text == null || text.Length == 0)
                    text = Strings.FieldPicker.UnnamedField;
                text = "    " + text;

                // show custom fields' types:
                if (item.GetType() != typeof(Field))
                    text = string.Format("{0} ({1})", text, item.GetType().Name);

                if (f.Calculated)
                    brush = SystemBrushes.Highlight;
            }

            // select brush for highlighted item
            if ((e.State & (DrawItemState.Selected | DrawItemState.HotLight)) != 0)
            {
                brush = SystemBrushes.HighlightText;
                backBrush = SystemBrushes.Highlight;
            }

            // draw item
            e.Graphics.FillRectangle(backBrush, e.Bounds);
            e.Graphics.DrawString(text, e.Font, brush, e.Bounds);
        }

		protected override void OnDropDown(EventArgs e)
		{
			FillList();
			base.OnDropDown (e);
        }

        #endregion
    }
}
