//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "uMain.h"
#include "uDockForm.h"
#include "uTabHost.h"
#include "uConjoinHost.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
const TColor Colors[7] = {
  clWhite, clBlue, clGreen, clRed, clTeal, clPurple, clLime};
const char *ColStr[] = {
  "White", "Blue", "Green", "Red", "Teal", "Purple", "Lime"};

TDockableForm *DockWindows[7];
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormCreate(TObject *Sender)
{
  CreateDockableWindows();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CreateDockableWindows(void)
{
  for (int I = 0; I <= 6; I++)
  {
	DockWindows[I] = new TDockableForm(Application);
	DockWindows[I]->Caption = ColStr[I];
	DockWindows[I]->Memo1->Color = Colors[I];
	DockWindows[I]->Memo1->Font->Color = (Colors[I] ^ 0x00FFFFFF);
	DockWindows[I]->Memo1->Text = AnsiString(ColStr[I]) + " window ";
  };
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CoolBar1DockOver(TObject *Sender,
      TDragDockObject *Source, int X, int Y, TDragState State, bool &Accept)
{
  Accept = (dynamic_cast<TToolBar*>(Source->Control) != NULL);
  if (Accept)
  {
    // Modify the DockRect to preview dock area (Coolbar client area)
    Types::TPoint TopLeft = Types::TPoint(CoolBar1->ClientRect.Left, CoolBar1->ClientRect.Top);
    TopLeft = CoolBar1->ClientToScreen(TopLeft);

    Types::TPoint BottomRight = Types::TPoint(CoolBar1->ClientRect.Right, CoolBar1->ClientRect.Bottom);
    BottomRight = CoolBar1->ClientToScreen(BottomRight);

    Source->DockRect = Types::TRect(TopLeft, BottomRight);
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ViewToolBar1Execute(TObject *Sender)
{
  //Toggles the visible state of Toolbar1, regardless of it's docked state.
  ToolBar11->Checked = !ToolBar11->Checked;
  btnToolBar1->Down = ToolBar11->Checked;
  if (ToolBar1->Floating)
	ToolBar1->HostDockSite->Visible = ToolBar11->Checked;
  else
	ToolBar1->Visible = ToolBar11->Checked;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ViewToolBar2Execute(TObject *Sender)
{
  //Toggles the visible state of Toolbar2, regardless of it's docked state.
  ToolBar21->Checked = !ToolBar21->Checked;
  btnToolBar2->Down = ToolBar21->Checked;
  if (ToolBar2->Floating)
	ToolBar2->HostDockSite->Visible = ToolBar21->Checked;
  else
	ToolBar2->Visible = ToolBar21->Checked;
}
//---------------------------------------------------------------------------
// BeginExample: OnDock
// Event: Controls.TWinControl.OnUnDock
// Event: Controls.TWinControl.OnDockDrop
// Event: Controls.TWinControl.OnDockOver
// Event: Controls.TWinControl.OnGetSiteInfo
// Property: Controls.TWinControl.DockManager
// Method: Controls.IDockManager.ResetBounds
// Method: Controls.TControl.ClientToScreen
// Property: Controls.TDragDockObject.DockRect

// BeginCode
/*
The following example is taken from the docking demo. It
shows how set permissions to dock dockable objects onto a
docking site.
*/

void __fastcall TMainForm::LeftDockPanelDockDrop(TObject *Sender,
      TDragDockObject *Source, int X, int Y)
{
  //OnDockDrop gets called AFTER the client has actually docked,
  //so we check for DockClientCount = 1 before making the dock panel visible.
  TPanel *panel = dynamic_cast<TPanel *>(Sender);
  if (panel->DockClientCount == 1)
	ShowDockPanel(panel, True, NULL);
  panel->DockManager->ResetBounds(True);
  //Make DockManager repaints it's clients.
}

void __fastcall TMainForm::LeftDockPanelDockOver(TObject *Sender,
	  TDragDockObject *Source, int X, int Y, TDragState State, bool &Accept)
{
  Accept = (dynamic_cast<TDockableForm*>(Source->Control) != NULL);
  if (Accept)
  {
    // Modify the DockRect to preview dock area.
    Types::TPoint TopLeft = LeftDockPanel->ClientToScreen(Point(0, 0));
	Types::TPoint BottomRight = LeftDockPanel->ClientToScreen(
	  Point(this->ClientWidth/3, LeftDockPanel->Height));
	Source->DockRect = Types::TRect(TopLeft, BottomRight);
  }
}

void __fastcall TMainForm::LeftDockPanelUnDock(TObject *Sender,
	  TControl *Client, TWinControl *NewTarget, bool &Allow)
{
  //OnUnDock gets called BEFORE the client is undocked, in order to optionally
  //disallow the undock. DockClientCount is never 0 when called from this event.
  TPanel *panel = dynamic_cast<TPanel *>(Sender);
  if (panel->DockClientCount == 1)
	ShowDockPanel(panel, False, NULL);
}

void __fastcall TMainForm::LeftDockPanelGetSiteInfo(TObject *Sender,
	  TControl *DockClient, TRect &InfluenceRect, TPoint &MousePos,
	  bool &CanDock)
{
  //if CanDock is true, the panel will not automatically draw the preview rect.
  CanDock = DockClient->ClassNameIs("TDockableForm");
  if (!CanDock)
  {
     ShowMessage(L"GetSiteInfo CanDock went bad!");
  }
}
// EndCode
// EndExample: OnDock
//---------------------------------------------------------------------------

void __fastcall TMainForm::BottomDockPanelDockOver(TObject *Sender,
	  TDragDockObject *Source, int X, int Y, TDragState State, bool &Accept)
{
  Accept = (dynamic_cast<TDockableForm*>(Source->Control) != NULL);
  if (Accept)
  {
    // Modify the DockRect to preview dock area.
    Types::TPoint TopLeft = BottomDockPanel->ClientToScreen(
      Point(0, -this->ClientHeight / 3));
    Types::TPoint BottomRight = BottomDockPanel->ClientToScreen(
      Point(BottomDockPanel->Width, BottomDockPanel->Height));
    Source->DockRect = Types::TRect(TopLeft, BottomRight);
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShowDockPanel(TPanel *APanel, bool MakeVisible, TControl *Client)
{
  //Client - the docked client to show if we are re-showing the panel.
  //Client is ignored if hiding the panel.

  //Since docking to a non-visible docksite isn't allowed, instead of setting
  //Visible for the panels we set the width to zero. The default InfluenceRect
  //for a control extends a few pixels beyond it's boundaries, so it is possible
  //to dock to zero width controls.

  //Don't try to hide a panel which has visible dock clients.
  if (!MakeVisible && (APanel->VisibleDockClientCount > 1))
	return;

  if (APanel == LeftDockPanel)
	VSplitter->Visible = MakeVisible;
  else
	HSplitter->Visible = MakeVisible;

  if (MakeVisible)
  {
	if (APanel == LeftDockPanel)
	{
	  APanel->Width = ClientWidth / 3;
	  VSplitter->Left = APanel->Width + VSplitter->Width;
	}
	else
	{
	  APanel->Height = ClientHeight / 3;
	  HSplitter->Top = ClientHeight - APanel->Height - HSplitter->Width;
	};
  }
  else
  {
	if (APanel == LeftDockPanel)
	  APanel->Width = 0;
	else
	  APanel->Height = 0;
  }
  if (MakeVisible && (Client != NULL)) Client->Show();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ExitActionExecute(TObject *Sender)
{
  Close();
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::ViewWhiteWindowExecute(TObject *Sender)
{

  TDockableForm *DockWindow = DockWindows[dynamic_cast<TComponent *>(Sender)->Tag];
  //if the docked window is TabDocked, it is docked to the PageControl
  //(owned by TTabDockHost) so show the host form.
  if ((DockWindow->HostDockSite != NULL) && DockWindow->HostDockSite->ClassNameIs("TPageControl"))
	(dynamic_cast<TTabDockHost *>(DockWindow->HostDockSite->Owner))->Show();
  //If window is conjoin-docked, host and/or form may not be visible
  //so show both.
  else if ((DockWindow->HostDockSite != NULL) && DockWindow->HostDockSite->ClassNameIs("TConjoinDockHost") &&
	  !DockWindow->HostDockSite->Visible)
  {
	DockWindow->HostDockSite->Show();
	(dynamic_cast<TConjoinDockHost *>(DockWindow->HostDockSite))->UpdateCaption(NULL);
	DockWindow->Show();
  }
  //If form is docked to one of the "hidden" docking panels, resize the
  //panel and re-show the docked form.
  else if ((DockWindow->HostDockSite != NULL) && DockWindow->HostDockSite->ClassNameIs("TPanel")
		&& ((DockWindow->HostDockSite->Height == 0) || (DockWindow->HostDockSite->Width == 0)))
		MainForm->ShowDockPanel(dynamic_cast<TPanel *>(DockWindow->HostDockSite), True, DockWindow);
  else
	//if the window isn't docked at all, simply show it.
	DockWindow->Show();
}
//---------------------------------------------------------------------------


