using System.Drawing;
using System.Windows.Forms;
namespace DevComponents.DotNetBar
{
	/// 
	/// Summary description for DesignTimeProviderContainer.
	/// 
	public class DesignTimeProviderContainer
	{
		/// 
		/// Returns information about insertion position for an item given screen coordinates. Used internally for drag&drop support.
		/// 
		/// Container item
		/// Screen coordinates
		/// Item that is being dragged
		/// Information about insertion position or null if item cannot be inserted to the container.
		public static InsertPosition GetInsertPosition(BaseItem containerItem, Point pScreen, BaseItem DragItem)
		{
			InsertPosition objInsertPos=null;
            Control objContainer = null;
            if (containerItem is PopupItem && containerItem.Expanded)
                objContainer = ((PopupItem)containerItem).PopupControl;
            else
                objContainer = containerItem.ContainerControl as Control;
            if (objContainer == null)
				return null;
			Point pClient=objContainer.PointToClient(pScreen);
			Rectangle thisRect=containerItem.DisplayRectangle;
            if (containerItem is PopupItem && containerItem.Expanded)
                thisRect = objContainer.DisplayRectangle;
			if(thisRect.Contains(pClient) || containerItem.SubItems.Count==0 && objContainer.ClientRectangle.Contains(pClient) || containerItem is ItemContainer && ((ItemContainer)containerItem).SystemContainer && objContainer.ClientRectangle.Contains(pClient))
			{
				Rectangle r;
				BaseItem objItem;
				// Check first inside any expanded items
				objItem=containerItem.ExpandedItem();
				if(objItem!=null)
				{
					IDesignTimeProvider provider=objItem as IDesignTimeProvider;
					if(provider!=null)
					{
						objInsertPos=provider.GetInsertPosition(pScreen, DragItem);
						if(objInsertPos!=null)
							return objInsertPos;
					}
				}
                bool dragItemPreviousItem = false;
				for(int i=0;i1 && containerItem.SubItems[containerItem.SubItems.Count-1].SystemItem)
						objInsertPos=new InsertPosition(containerItem.SubItems.Count-2,true,(IDesignTimeProvider)containerItem);
					else
						objInsertPos=new InsertPosition(containerItem.SubItems.Count-1,false,(IDesignTimeProvider)containerItem);
				}
			}
			else
			{
				foreach(BaseItem objItem in containerItem.SubItems)
				{
					if(objItem==DragItem)
						continue;
					IDesignTimeProvider provider=objItem as IDesignTimeProvider;
					if(provider!=null)
					{
						objInsertPos=provider.GetInsertPosition(pScreen, DragItem);
						if(objInsertPos!=null)
							break;
					}
				}				
			}
			return objInsertPos;
		}
	    private static bool CanExpand(BaseItem objItem)
	    {
	        return (objItem is PopupItem && (objItem.SubItems.Count > 0 || objItem.IsOnMenuBar)) || objItem is ItemContainer && ((ItemContainer)objItem).CanExpand;
	    }
	    /// 
		/// Draws reversible marker to indicates item drag&drop position
		/// 
		/// Container item
		/// Position to draw marker at
		/// Indicates whether the marker is drawn before the reference position
		public static void DrawReversibleMarker(BaseItem containerItem, int iPos, bool Before)
		{
			Control objCtrl=containerItem.ContainerControl as Control;
			if(objCtrl==null)
				return;
			BaseItem objItem=null;
			if(iPos>=0)
				objItem=containerItem.SubItems[iPos];
			Rectangle r, rl,rr;
			if(objItem!=null)
			{
				if(objItem.DesignInsertMarker!=eDesignInsertPosition.None)
					objItem.DesignInsertMarker=eDesignInsertPosition.None;
				else if(Before)
					objItem.DesignInsertMarker=eDesignInsertPosition.Before;
				else
					objItem.DesignInsertMarker=eDesignInsertPosition.After;
				return;
			}
			else
			{
				Rectangle rTmp=containerItem.DisplayRectangle;
				rTmp.Inflate(-1,-1);
				r=new Rectangle(rTmp.Left+2,rTmp.Top+2,1,rTmp.Height-4);
				rl=new Rectangle(rTmp.Left,rTmp.Top+1,5,1);
				rr=new Rectangle(rTmp.Left,rTmp.Bottom-2,5,1);
			}
            //r.Location=objCtrl.PointToScreen(r.Location);
            //rl.Location=objCtrl.PointToScreen(rl.Location);
            //rr.Location=objCtrl.PointToScreen(rr.Location);
            //ControlPaint.DrawReversibleFrame(r,SystemColors.Control,FrameStyle.Thick);
            //ControlPaint.DrawReversibleFrame(rl,SystemColors.Control,FrameStyle.Thick);
            //ControlPaint.DrawReversibleFrame(rr,SystemColors.Control,FrameStyle.Thick);
		}
		/// 
		/// Inserts drag&drop item at specified position.
		/// 
		/// Container item.
		/// Item being inserted
		/// Insertion position
		/// Indicates whether item is inserted before the specified insertion position
		public static void InsertItemAt(BaseItem containerItem, BaseItem objItem, int iPos, bool Before)
		{
			if(containerItem.ExpandedItem()!=null)
			{
				containerItem.ExpandedItem().Expanded=false;
			}
			if(!Before)
			{
				if(iPos+1>=containerItem.SubItems.Count)
				{
					containerItem.SubItems.Add(objItem,GetAppendPosition(containerItem));
				}
				else
				{
					containerItem.SubItems.Add(objItem,iPos+1);
				}
			}
			else
			{
				if(iPos>=containerItem.SubItems.Count)
				{
					containerItem.SubItems.Add(objItem, GetAppendPosition(containerItem));
				}
				else
				{
					containerItem.SubItems.Add(objItem,iPos);
				}
			}
			if(containerItem.ContainerControl is Bar)
				((Bar)containerItem.ContainerControl).RecalcLayout();
			else if(containerItem.ContainerControl is MenuPanel)
				((MenuPanel)containerItem.ContainerControl).RecalcSize();
			else if(containerItem.ContainerControl is BarBaseControl)
				((BarBaseControl)containerItem.ContainerControl).RecalcLayout();
			else if(containerItem.ContainerControl is ItemControl)
				((ItemControl)containerItem.ContainerControl).RecalcLayout();
			else
			{
				containerItem.RecalcSize();
				containerItem.Refresh();
			}
		}
		/// 
		/// Returns insertion index for an item taking in account any system items that are at the end of the collection.
		/// 
		/// Parent item
		/// Returns the index at which an item should be inserted
		public static int GetAppendPosition(BaseItem objParent)
		{
			int iPos=-1;
			for(int i=objParent.SubItems.Count-1;i>=0;i--)
			{
				if(objParent.SubItems[i].SystemItem)
					iPos=i;
				else
					break;
			}
			return iPos;
		}
	}
}