/*******************************************************}
{                                                       }
{               Borland DB Web                          }
{           Data aware Web controls                     }
{  Copyright (c) 2003 Borland Software Corporation      }
{                                                       }
{*******************************************************/

using System;
using System.Data;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Drawing.Design;
using System.Text;


namespace Borland.Data.Web
{

   #region DBWebLabeledTextBox

	public enum LabelPosition
   {
   	LabelToLeft,
      LabelAbove,
      LabelToRight,
      LabelBelow
   }

	/// <summary>
	/// Data aware Label control for use with DBWebDataSource
	/// </summary>

	[Designer("Borland.Data.Web.DBWebControlDesigner"),
   ToolboxBitmap(typeof(Borland.Data.Web.DBWebLabeledTextBox),
   "Borland.Data.Web.DBWebLabeledTextBox.bmp"),
	ToolboxData("<{0}:DBWebLabeledTextBox runat=server></{0}:DBWebLabeledTextBox>")]
   public class DBWebLabeledTextBox : WebControl, IDBWebColumnLink, IPostBackDataHandler
   {
      private const int minWidth = 120;
   	private const string childPrefix = "TB_";
      private const string defaultTextBoxPortion = "100%";
      private string FTextBoxPortion;
      private LabelPosition FLabelPosition;
      private Label FLabel;
      private System.Web.UI.WebControls.Panel FPanel;
      private Color FCaptionBackColor;
      private Color FCaptionForeColor;
      private DBWebColumnLink FColumnLink;
      private IDBWebColumnLink IColumnLink;
      private TextBox FTextBox;
      private bool FReadOnly;
      private bool FCaptionFontBold;
      private bool FCaptionFontItalic;
      private bool FCaptionFontUnderline;
      private bool FCaptionFontOverline;
      private FontUnit FCaptionFontSize;


   	public DBWebLabeledTextBox() : base()
      {
      	FTextBox = new TextBox();
         FLabel = new Label();
         FPanel = new System.Web.UI.WebControls.Panel();
      	FTextBoxPortion = defaultTextBoxPortion;
         FLabelPosition = LabelPosition.LabelToLeft;
         FColumnLink = new DBWebColumnLink(this);
         IColumnLink = (FColumnLink as IDBWebColumnLink);
         FReadOnly = false;
         base.Width = Unit.Parse( Convert.ToString(minWidth) + "px");
      }

		protected override void OnPreRender(EventArgs args)
		{
			base.OnPreRender(args);
			string s = Page.Request.QueryString[DBWebConst.sBorlandImageID];
         if( s != null )
         	return;
         DataBind();
         if( !ReadOnly )
         	Page.RegisterHiddenField(DBWebDataSource.IdentPrefix + this.ID, IColumnLink.TableName + DBWebConst.Splitter + IColumnLink.ColumnName);
		}

		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);
			if( Page != null )
				Page.RegisterRequiresPostBack(this);
      }

      #region IPostBackDataHandler
      // RaisePostDataChangedEvent is called prior to DataBind()
      // DataSet and related properties are NOT available here
      // Child controls are not available
		bool IPostBackDataHandler.LoadPostData(string postDataKey,
			NameValueCollection postCollection)
      {
         if( this.Visible )
	      	FColumnLink.LoadPostData(postDataKey, postCollection);
         return false;
      }

	   void IPostBackDataHandler.RaisePostDataChangedEvent()
   	{
	   }
      #endregion
      
      #region IDBWebDataLink
      string IDBWebDataLink.TableName
      {
      	get
         {
         	return IColumnLink.TableName;
         }
         set
         {
         	IColumnLink.TableName = value;
         }
      }
      IDBDataSource IDBWebDataLink.DBDataSource
      {
      	get
         {
         	return IColumnLink .DBDataSource;
         }
         set
         {
         	IColumnLink.DBDataSource = value;
         }
      }
      #endregion
      #region IDBWebColumnLink
      string IDBWebColumnLink.ColumnName
      {
      	get
         {
         	return IColumnLink.ColumnName;
         }
         set
         {
         	IColumnLink.ColumnName = value;
         }
      }
      #endregion

      [Editor(typeof(Borland.Data.Web.TableNamePropEditor), typeof(UITypeEditor)),
		LocalizableCategoryAttribute("DBWebControl"),
		DefaultValue(null)]
      public string TableName
      {
      	get
         {
	      	return IColumnLink.TableName;
         }
      	set
         {
	      	IColumnLink.TableName = value;
         }
      }
		[LocalizableCategoryAttribute("DBWebControl"),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
		DefaultValue(null)]
      public IDBDataSource DBDataSource
      {
      	get
         {
         	return IColumnLink.DBDataSource;
         }
         set
         {
         	IColumnLink.DBDataSource = value;
         }
      }


      [Editor(typeof(Borland.Data.Web.ColumnNamePropEditor), typeof(UITypeEditor)),
		LocalizableCategoryAttribute("DBWebControl"),
		DefaultValue(null)]
      public string ColumnName
      {
      	get
         {
         	return IColumnLink.ColumnName;
         }
         set
         {
         	IColumnLink.ColumnName = value;
         }
      }

		[LocalizableCategoryAttribute("Behavior"),
		DefaultValue(false)]
      public bool ReadOnly
      {
      	get
         {
	      	return FReadOnly;
         }
      	set
         {
	      	FReadOnly = value;
         }
      }
      
      protected string ChildPrefix
      {
      	get
         {
         	return childPrefix;
         }
      }

      private int PercentValue( string s )
      {
      	try
         {
         	int iPercentPos = s.IndexOf("%" );
            string sNumber = s.Substring(0, iPercentPos);
            int iPercent = Convert.ToInt32(sNumber);
            if( iPercent > 0 && iPercent < 101 )
            	return iPercent;
         }
         catch
         {
         	// invalid percent value: don't use
         }
         return -1;
      }

		#region caption properties
		[LocalizableCategoryAttribute("Caption"),
      DefaultValue("")]
      public string Caption
      {
      	get
         {
         	return FLabel.Text;
         }
         set
         {
            if( FLabel.Text != value )
            {
         		FLabel.Text = value;
               if( FTextBoxPortion == defaultTextBoxPortion )
               	FTextBoxPortion = "50%";
            }
         }
      }

		[LocalizableCategoryAttribute("Caption"),
      DefaultValue("LabelPosition.LabelOnTop")]
      public LabelPosition CaptionPosition
      {
      	get
         {
         	return FLabelPosition;
         }
      	set
         {
         	FLabelPosition = value;
         }
      }

		[LocalizableCategoryAttribute("Caption"),
      DefaultValue("100%")]
      public string TextBoxPortion
      {
      	get
         {
         	return FTextBoxPortion;
         }
      	set
         {
            if( FTextBoxPortion != value )
            {
         		int iPercentPos = value.IndexOf("%" );
            	if( iPercentPos < 0 )
            		value = value + "%";
            	if( PercentValue( value ) != -1 )
          				FTextBoxPortion = value;
            }
         }
      }
		[LocalizableCategoryAttribute("Caption")]
      public Color CaptionBackColor
      {
      	get
         {
         	return FCaptionBackColor;
         }
         set
         {
         	FCaptionBackColor = value;
         }
      }

		[LocalizableCategoryAttribute("Caption")]
      public Color CaptionForeColor
      {
      	get
         {
         	return FCaptionForeColor;
         }
         set
         {
         	FCaptionForeColor = value;
         }
      }

		[LocalizableCategoryAttribute("Caption")]
      public bool CaptionFontItalic
      {
      	get
         {
         	return FCaptionFontItalic;
         }
         set
         {
         	FCaptionFontItalic = value;
         }
      }

		[LocalizableCategoryAttribute("Caption")]
      public bool CaptionFontUnderline
      {
      	get
         {
         	return FCaptionFontUnderline;
         }
         set
         {
         	FCaptionFontUnderline = value;
         }
      }
		[LocalizableCategoryAttribute("Caption")]
      public bool CaptionFontOverline
      {
      	get
         {
         	return FCaptionFontOverline;
         }
         set
         {
         	FCaptionFontOverline = value;
         }
      }
      public FontUnit CaptionFontSize
      {
      	get
         {
         	return FCaptionFontSize;
         }
         set
         {
         	FCaptionFontSize = value;
         }
      }

		[LocalizableCategoryAttribute("Caption")]
      public bool CaptionFontBold
      {
      	get
         {
         	return FCaptionFontBold;
         }
         set
         {
         	FCaptionFontBold = value;
         }
      }
      #endregion

      public string ControlID()
      {
      	return ChildPrefix + this.ID;
      }

      private void SetControlSize(WebControl control, int portion)
      {
         double divisor = 100 / Convert.ToDouble(portion);
         double dSize;
         if( base.Width.Value < minWidth )
         	base.Width = Unit.Parse(Convert.ToString(minWidth) + "px");
         dSize = (base.Width.Value / divisor) - ( (2 + base.BorderWidth.Value) * 2);
         string sSize = dSize.ToString();
         int iDotPos = sSize.IndexOf(".");
         if( iDotPos > 0 )
            sSize = sSize.Substring(0, iDotPos );
         control.Width = Unit.Parse(sSize + "px");
      }

      private void SetLabelProps( )
      {
	      FLabel.BackColor = FCaptionBackColor;
   	   FLabel.ForeColor = FCaptionForeColor;
      }

      private void SetProportionalSize()
      {

      	int iTextPortion;
         if( FLabelPosition == LabelPosition.LabelAbove ||
         		FLabelPosition == LabelPosition.LabelBelow )
         {
            FPanel.Wrap = true;
         	FTextBox.Width = Unit.Parse(base.Width.Value.ToString() + "px");
         	FLabel.Width = Unit.Parse(base.Width.Value.ToString() + "px");
         }
         else
         {
            FPanel.Wrap = false;
          	iTextPortion = PercentValue(FTextBoxPortion);
	         if( iTextPortion == -1 )
   	      	iTextPortion = 50;
		      SetControlSize(FTextBox, iTextPortion);
            if( !ClassUtils.IsEmpty(this.Caption) )
		         SetControlSize(FLabel, 100 - iTextPortion);
         }
         SetLabelProps();
      }

      private void SetLabelFont()
      {
      	FLabel.Font.Bold = FCaptionFontBold;
      	FLabel.Font.Italic = FCaptionFontItalic;
      	FLabel.Font.Overline = FCaptionFontOverline;
      	FLabel.Font.Underline = FCaptionFontUnderline;
      	FLabel.Font.Size = FCaptionFontSize;
      }

		public override void DataBind()
      {
      	try
         {
	         FTextBox.ReadOnly = FReadOnly;
   	   	FTextBox.ID = this.ID;
      		base.DataBind();
         	ClassUtils.SetBehaviorProperties(FPanel, this);
	         ClassUtils.SetOuterAppearanceProperties(FPanel, this);
   	      ClassUtils.SetSizeProperties(FPanel, this);
      	   if( !ClassUtils.IsEmpty(FLabel.Text) )
         	{
         		ClassUtils.SetInnerAppearanceProperties(FLabel, this);
	            SetProportionalSize();
               SetLabelFont();
   	         FTextBox.Text = null;
      	   }
      		if( IColumnLink.DBDataSource != null )
	         {
   	         if( IColumnLink.DBDataSource.IsDataBound(IColumnLink.TableName) )
      	      {
         			ClassUtils.SetBehaviorProperties(FTextBox, this);
			         ClassUtils.SetAppearanceProperties(FTextBox, this);
   			      ClassUtils.SetSizeProperties(FTextBox, this);
	      	   	object o = IColumnLink.DBDataSource.GetColumnValue(Page,
   	      	   		IColumnLink.TableName, IColumnLink.ColumnName);
      	      	if( o != null )
            			FTextBox.Text = Convert.ToString(o);
	               else
   	               FTextBox.Text = "";
      	         FTextBox.DataBind();
         	   }
            }
         }
         catch(Exception ex)
         {
         	if( !ClassUtils.IsDesignTime(Page) )
            {
	            Page.Response.Write(ClassUtils.GetInternalError(Page, IColumnLink, ex, this.ID));
            }
            else
            	throw new Exception(ex.Message);
         }
      }

		protected override void Render(HtmlTextWriter output)
		{
      	bool error = ClassUtils.OutputErrors(Page, output, IColumnLink);
         if( !error || (IColumnLink.DBDataSource as DBWebDataSource).ErrorOption != ErrorHtmlOption.logOnErrorPage )
				output.Write(Text);
         else  // if going to a separate error hmtl page, output "OK" button.
         {
         	ClassUtils.OutputOKButton(output);
            Page.Response.End();
         }
		}

		protected string Text
		{
			get
			{
         	StringWriter sw = new StringWriter();
				HtmlTextWriter tw = new HtmlTextWriter(sw);
            ClassUtils.AddStyleToPanel(FPanel, this.Style);
            FPanel.RenderBeginTag(tw);
            string text = sw.ToString();
            if( ClassUtils.IsEmpty(FLabel.Text) )
            {
            	FTextBox.Width = this.Width;
               FTextBox.Height = this.Height;
            }
            if( FLabelPosition == LabelPosition.LabelAbove ||
            		FLabelPosition == LabelPosition.LabelToLeft )
            {
      			if( !ClassUtils.IsEmpty(FLabel.Text) )
            		FLabel.RenderControl(tw);
            	FTextBox.RenderControl(tw);
            }
            else
            {
            	FTextBox.RenderControl(tw);
      			if( !ClassUtils.IsEmpty(FLabel.Text) )
            		FLabel.RenderControl(tw);
            }
            if( text != null )
            	text = sw.ToString();
            FPanel.RenderEndTag(tw);
            if( text != null )
            	text = sw.ToString();
            return sw.ToString();
			}
		}

   }
   #endregion
}
