using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using VEPROMS.CSLA.Library;
using Volian.Base.Library;
namespace Volian.Controls.Library
{
	public partial class RtfRawItem : EditItem
	{
		#region IEditItem
		public override StepRTB MyStepRTB
		{
			get { return _MyStepRTB; }
		}
		public override int TableWidth
		{
			get
			{
				return (int)_MyStepRTB.Width + RtfRawMargin;
			}
		}
		/// 
		/// The left edge of the Tab (no visible tab, but use this for EditItem interfacing
		/// 
		public override int ItemLeft
		{
			get { return Left + lblTab.Left; }
			set { Left = value - lblTab.Left; }
		}
		/// 
		/// The Location of the Tab
		/// 
		public override Point ItemLocation
		{
			get { return new Point(Location.X + lblTab.Left, Location.Y); }
			set { Location = new Point(value.X - lblTab.Left, value.Y); }
		}
		/// 
		/// Width of the Tab and RichTextBox
		/// 
		public override int ItemWidth
		{
			get { return Width - lblTab.Left; }
			set
			{
				Width = RtfRawMargin + value + lblTab.Left;
			}
		}
		/// 
		/// Width of the RichTextBox
		/// 
		public override int ContentWidth
		{
			get { return _MyStepRTB.Width; }
			set
			{
				Width = value + lblTab.Left + lblTab.Width;
			}
		}
		public override int BorderWidth { get { return (_MyStepRTB.Width - _MyStepRTB.ClientRectangle.Width); } }
		/// 
		/// Location of the RichTextBox
		/// 
		public override Point ContentLocation
		{
			get { return new Point(Location.X + _MyStepRTB.Left, Location.Y); }
			set { Location = new Point(value.X - _MyStepRTB.Left, value.Y); }
		}
		/// 
		/// Left edge of the RichTextBox
		/// 
		public override int ContentLeft
		{
			get { return Left + _MyStepRTB.Left; }
		}
		override public void AdjustTableWidthAndLocation()
		{
			Size sz = GetRtfRawSize(MyItemInfo.MyContent.Text);
			string tmp = MyItemInfo.MyContent.Text;
			if (MyItemInfo.MyContent.Text == "New Step") tmp = "";	// if coming from the tree view/insert before or after - rtf is 'New Step'
			MyStepRTB.Rtf = tmp;
			MyStepRTB.Width = sz.Width;
			MyStepRTB.Height = sz.Height;
			ItemLocation = TableLocation(MyStepSectionLayoutData, ItemWidth);
			Width = sz.Width; 
			Height = _MyStepRTB.Height + _MyStepRTB.Top + 7;
			ItemWidth = Width;
		}
		override public void SetToolTip(string tip)
		{
			DevComponents.DotNetBar.SuperTooltipInfo tpi = new DevComponents.DotNetBar.SuperTooltipInfo("", "", tip, null, null, DevComponents.DotNetBar.eTooltipColor.Lemon);
			_MyToolTip.MinimumTooltipSize = new Size(0, 24);
			_MyToolTip.TooltipDuration = 3;
			_MyToolTip.SetSuperTooltip(MyStepRTB, tpi);
		}
		public override void RefreshContent()
		{
			IdentifyMe(false);
			MyStepRTB.Rtf = MyItemInfo.MyContent.Text;
			RefreshDisplay(false);
		}
		public override void RefreshOrdinal()
		{
			TabFormat = null;
		} 
		public override void HandleResize() {}
		public override void MatchExpanded() {}
		public override void ItemSelect()
		{
			// Was getting an Error that _MyStepRTB was Disposed RHM 20101217
			if (!_MyStepRTB.Disposing && !_MyStepRTB.Closed)
			{
				_MyStepRTB.Focus();
			}
			else
			{
				_MyLog.WarnFormat("Attempt to give Focus to Disposed Object {0}", MyID);
			}
			ScrollToCenter();
		}
		/// 
		/// Sets the focus to this RTBItem
		/// 
		public override void ItemShow()
		{
			_MyStepRTB.Focus();
			ScrollToCenter();
		}
		public override void SetActive()
		{
			this.BackColor = MyStepPanel.ActiveColor;
		}
		public override void SetText()
		{
			LastMethodsPush("SetText");
			if (MyItemInfo != null)
			{
				MyStepRTB.MyItemInfo = MyItemInfo;
				IdentifyMe(false);
			}
			LastMethodsPop();
		}
		public override void SetExpandAndExpander(ItemInfo itemInfo)
		{
			CanExpand = false;
		}
		public override void SaveCurrentAndContents()
		{
			SaveContents();
		}
		public override void RefreshDisplay(bool activeMode)
		{
			MyStepRTB.VwMode = MyStepPanel.VwMode; 
			Size sz = GetRtfRawSize(MyStepRTB.Rtf);
			if (MyStepRTB.Rtf == null || MyStepRTB.Rtf == ""  
				|| !(MyStepRTB.Rtf.ToUpper().Contains("OBJCLASS EQU")
				|| MyStepRTB.Rtf.ToUpper().Contains("OBJCLASS VIS")) //Support Visio
				)	// this is a new insert
			{
				sz.Width = 50;
				sz.Height = 50;
			}
			MyStepRTB.Width = sz.Width;
			MyStepRTB.Height = sz.Height;
			if (_MyParentEditItem != null) ItemLocation = new Point(300, _MyParentEditItem.Bottom);
			ItemLocation = TableLocation(MyStepSectionLayoutData, ItemWidth);
			Width = sz.Width;
			Height = _MyStepRTB.Height + _MyStepRTB.Top + 7;
			ItemWidth = Width;
			MyStepPanel.MyStepTabPanel.MyStepTabRibbon.SetButtonAndMenuEnabling(true); 
		}
		public override void ToggleEditView(E_ViewMode vwMode)
		{
			SaveContents();
		}
		public override string TabFormat
		{
			get { return null; }
			set { ;}
		}
		public override bool Expanded
		{
			get { return true; }
			set { ; }
		}
		public override bool CanExpand
		{
			get { return false; }
			set { ; }
		}
		public override int TabLeft { get { return lblTab.Left; } set { lblTab.Left = value; } }	//taken from griditem
		public override Font TabFont { get { return MyStepRTB.Font; } set { ; } }
		public override string TabText { get { return lblTab.Text; } }
		public override Point TabLocation { get { return lblTab.Location; } }
		public override Font ContentFont { get { return MyStepRTB.Font; } set { /*MyStepRTB.Font = value*/; } }
		public override float ContentTop { get { return MyStepRTB.Top; } }
		public override DialogResult ReplaceText(string rpltxt, string fndstr, bool caseSensitive, bool matchWholeWord, bool reverse, bool prompt, IWin32Window fndrpldlg)
		{
			return DialogResult.OK;
		}
		public override bool FindText(string str, bool caseSensitive, bool matchWholeWord, bool reverse)
		{
			return false;
		}
		public override void PositionToEnd()
		{
			return;
		}
		public override void PositionToStart()
		{
			return;
		}
		public override string SelectedTextForFind
		{
			get {return null;}
		}
		public override bool SpellCheckNext()
		{
			return false;
		}
		public override bool Empty
		{
			get
			{
				return _MyStepRTB.Text == "";
			}
			set { _MyStepRTB.Text = value ? "" : " "; }
		}
		public override void RefreshTab()
		{
			TabFormat = null;
		}
		public override void SetupHeader(ItemInfo itemInfo)
		{
			return;
		}
		public override void ShowExpanded() {}
		#endregion
		#region Properties
		private static int _RtfRawMargin = 6;	// make it a little bigger than rtbitems so it can be seen
		/// 
		/// Margin between the EditItem and the RtfRawItem.  Appears on the Right.
		/// Will allow space to draw a Change Bar on the right side of the EditItem.
		/// 
		public static int RtfRawMargin
		{
			get { return _RtfRawMargin; }
			set { _RtfRawMargin = value; }
		}
		#endregion
		#region Constructors
		public RtfRawItem()
		{
			InitializeComponent();
		}
		//existing objects:
		public RtfRawItem(ItemInfo itemInfo, StepPanel myStepPanel, EditItem myParentEditItem, ChildRelation myChildRelation, bool expand)
		{
			InitializeComponent();
			MyItemInfo = itemInfo;
			SetupEditItem(itemInfo, myStepPanel, myParentEditItem, myChildRelation, expand, null, false);
			AdjustTableWidthAndLocation();
			SetupEventHandlers();
			MyStepRTB.ReadOnly = !UserInfo.CanEdit(StepRTB.MyUserInfo, MyItemInfo.MyDocVersion); // reviewer cannot make changes to a table
			MyStepRTB.Enabled = UserInfo.CanEdit(StepRTB.MyUserInfo, MyItemInfo.MyDocVersion);
			MyStepRTB.OrigRTF = MyStepRTB.Rtf;
			this.Controls.Add(this._MyStepRTB);
			_origBitmap = GetBitmap(MyStepRTB.Rtf);  //kbr
		}
		// the following is for inserted equations:
		public RtfRawItem(ItemInfo itemInfo, StepPanel myStepPanel, EditItem myParentEditItem, ChildRelation myChildRelation, bool expand, EditItem nextEditItem)
		{
			InitializeComponent();
			MyItemInfo = itemInfo; 
			SetupEditItem(itemInfo, myStepPanel, myParentEditItem, myChildRelation, expand, nextEditItem, false);
			SetupEventHandlers();
			if (MyItemInfo.MyContent.Text != null && MyItemInfo.MyContent.Text != "") 
			{
				AdjustTableWidthAndLocation();
				MyStepRTB.OrigRTF = MyStepRTB.Rtf;
			}
			else
			{
				MyStepRTB.OrigRTF = "";
				MyStepRTB.Size = new Size(200, 200);
				Width = 200;
				Height = 200;
				ItemWidth = Width;
				ItemLocation = TableLocation(MyStepSectionLayoutData, ItemWidth);
			}
			this.Controls.Add(this._MyStepRTB);
		}
		private void SetupEventHandlers()
		{
			MyStepRTB.TextChanged += new EventHandler(MyStepRTB_TextChanged);
			MyStepRTB.Resize += new System.EventHandler(MyStepRTB_Resize);
			MyStepRTB.Enter += new System.EventHandler(_StepRTB_Enter);
			MyStepRTB.HeightChanged += new Volian.Controls.Library.StepRTBEvent(_MyStepRTB_HeightChanged);
			MyStepRTB.ContentsResized += new ContentsResizedEventHandler(MyStepRTB_ContentsResized);
			MyStepRTB.SetMenu += new StepRTBMenuEvent(MyStepRTB_SetMenu);
			MyStepRTB.CursorKeyPress += new Volian.Controls.Library.StepRTBCursorKeysEvent(MyStepRTB_CursorKeyPress);
			MyStepRTB.CursorMovement += new Volian.Controls.Library.StepRTBCursorMovementEvent(MyStepRTB_CursorMovement);
			Click += new EventHandler(RtfRawItem_Click);
			MyStepRTB.Click += new EventHandler(RtfRawItem_Click);
		}
		#endregion
		#region EventHandlers
		void RtfRawItem_Click(object sender, EventArgs e)
		{
			//if (MyStepPanel.DisplayItemChanging) return;
			MyStepPanel.SelectedEditItem = this;
		}
		private void _MyStepRTB_HeightChanged(object sender, EventArgs args)
		{
			if (this.Height != _MyStepRTB.Height + _MyStepRTB.Top + 7)  // add in 7 to make it look good // + 10)
			{
				LastMethodsPush(string.Format("_StepRTB_HeightChanged {0}", _MyStepRTB.Height));
				this.Height = _MyStepRTB.Height + _MyStepRTB.Top + 7;
				LastMethodsPop();
			}
		}
		public void MyStepRTB_ContentsResized(object sender, ContentsResizedEventArgs e)
		{
			// need duplicate call for this because for modifies & restores, a single call was not setting size correctly:
			RefreshDisplay(false);	
			RefreshDisplay(false);
		}
		void MyStepRTB_SetMenu(object sender, StepRTBMenuEventArgs args)
		{
			if (args.MenuGroup == null)
				MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ClearContextMenu();
			else if (args.MenuGroup == "OpenContextMenu")
				MyStepPanel.MyStepTabPanel.MyStepTabRibbon.SetContextMenu(sender);
			else
				MyStepPanel.MyStepTabPanel.MyStepTabRibbon.SetShortCutContextMenu(args.MenuGroup);
		}
		private void _StepRTB_Enter(object sender, EventArgs e)
		{
			if (MyStepPanel.DisplayItemChanging) return;
			MyStepPanel.SelectedEditItem = this;
		}
		#endregion
		#region Methods
		public override void SetFocus()
		{
			MyStepRTB.Focus();
		}
		public override void SaveContents()
		{
			SaveText();
			SaveConfig();
		}
		public void SaveText()
		{
			if (MyStepRTB.ReadOnly) return;
			if (!IsDirty()) return;
			try
			{
				string res = MyStepRTB.Rtf.Replace("\\par\r\n}", "}");
				using (Item _MyItem = MyItemInfo.Get())
				{
					_MyItem.MyContent.Text = res;
					_MyItem.MyContent.DTS = DateTime.Now;
					_MyItem.MyContent.UserID = Volian.Base.Library.VlnSettings.UserID;
					_MyItem.DTS = DateTime.Now;
					_MyItem.UserID = Volian.Base.Library.VlnSettings.UserID;
					_MyItem.Save();
				}
				_origBitmap = GetBitmap(res);
				MyStepRTB.ClearUndo();
			}
			catch (Exception ex)
			{
				//MessageBox.Show("The data could not be saved.", "Object Save", MessageBoxButtons.OK, MessageBoxIcon.Information);
				return;
			}
		}
		public System.Drawing.Bitmap GetBitmap(string rtf)
		{
			Bitmap bmap = null;
			try
			{
				System.Drawing.Size sz = RtfRawItem.GetRtfRawSize(rtf);
				Volian.Controls.Library.RTF myRtb = new RTF();
				myRtb.Size = sz;
				myRtb.Rtf = rtf;
				bmap = new System.Drawing.Bitmap((int)sz.Width, (int)sz.Height);
				System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(bmap);
				myRtb.RenderClipped(gr, new System.Drawing.Rectangle(0, 0, (int)sz.Width, (int)sz.Height));
			}
			catch (Exception ex)
			{
				return null;
			}
			return bmap;
		}
		private System.Drawing.Bitmap _origBitmap = null;
		private bool IsDirty()
		{
			System.Drawing.Bitmap curBitmap = GetBitmap(MyStepRTB.Rtf);
			if (_origBitmap == null) return true;
			return (!compare(_origBitmap, curBitmap));
		}
		// compares 2 bitmaps by comparing pixels between the 2.
		private bool compare(Bitmap bmp1, Bitmap bmp2)
		{
			bool equals = true;
			bool flag = true;  //Inner loop isn't broken
			//Test to see if we have the same size of image
			if (bmp1.Size == bmp2.Size)
			{
				for (int x = 0; x < bmp1.Width; ++x)
				{
					for (int y = 0; y < bmp1.Height; ++y)
					{
						if (bmp1.GetPixel(x, y) != bmp2.GetPixel(x, y))
						{
							equals = false;
							flag = false;
							break;
						}
					}
					if (!flag)
					{
						break;
					}
				}
			}
			else
			{
				equals = false;
			}
			return equals;
		}
		public override void IdentifyMe(bool highlight)
		{
			if (highlight)
				this.BackColor = Color.Gray;
			else
			{
				if (MyStepPanel.SelectedEditItem != null && MyStepPanel.SelectedEditItem.MyItemInfo == this.MyItemInfo)
					this.BackColor = MyStepPanel.ActiveColor;
				else
					this.BackColor = MyItemInfo.ItemAnnotationCount == 0 ? MyStepPanel.PanelColor : MyStepPanel.AnnotationColor;
			}
		}
		public static Size GetRtfRawSize(string rtf)
		{
			RichTextBox rtb = new RichTextBox();
			if (rtf == "New Step") rtf = "";			// if coming from the tree view/insert before or after - rtf is 'New Step'
			rtb.BorderStyle = BorderStyle.None;//Eliminate the border width
			rtb.Rtf = rtf; //  myRtf.Rtf;// set the contents
			rtb.AppendText(" ");// Add a space after the equation
			rtb.Width = 10000;// Start with a very wide richtextbox
			int w = rtb.GetPositionFromCharIndex(1).X;// Get the width of the equation
			rtb.Width = w;// Adjust the width
			int h = rtb.GetPositionFromCharIndex(2).Y;// Get the height of the equation
			return new Size(w, h);// Return the size of the Equation
		}
		void MyStepRTB_Resize(object sender, EventArgs e)
		{
			if (MyStepPanel != null && this == MyStepPanel.SelectedEditItem)
				ScrollToCenter();
		}
		void MyStepRTB_TextChanged(object sender, EventArgs e)
		{
			if (MyStepPanel != null && this == MyStepPanel.SelectedEditItem)
				ScrollToCenter();
		}
		private void MyStepRTB_CursorKeyPress(object sender, KeyEventArgs args)
		{
			MyStepPanel.StepCursorKeys(this, args);
		}
		private void MyStepRTB_CursorMovement(object sender, StepRTBCursorMovementEventArgs args)
		{
			MyStepPanel.CursorMovement(this, args.CursorLocation, args.Key);
		}
		#endregion
	}
}