/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: newsash.cpp,v 1.3 2001/03/14 13:48:11 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
    #pragma implementation "newsash.cpp"
    #pragma interface "newsash.h"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

#include "wx/pmf/newsash.h"

/***** Implementation for class wxNewSashLayoutWindow *****/

// "look-setting", defaults to "like Microsoft", 
// but can be surely overriden...

#define BTN_BOX_HEIGHT       12
#define BTN_BOX_WIDTH        12
#define BTN_X_WIEGHT         2

#define GROOVE_WIDTH         3  // left shade + middle line + right shade
#define GROOVE_TO_GROOVE_GAP 1  
#define GROOVE_COUNT         2
#define DRAG_HIND_WIDTH      ( (GROOVE_WIDTH+GROOVE_TO_GROOVE_GAP )*GROOVE_COUNT - GROOVE_TO_GROOVE_GAP )

#define SASH_MARGIN 2


IMPLEMENT_CLASS( wxNewSashLayoutWindow, wxSashLayoutWindow )

BEGIN_EVENT_TABLE( wxNewSashLayoutWindow, wxSashLayoutWindow )

	EVT_PAINT    ( wxNewSashLayoutWindow::OnPaint    )
	EVT_LEFT_DOWN( wxNewSashLayoutWindow::OnLeftDown )
	EVT_LEFT_UP  ( wxNewSashLayoutWindow::OnLeftUp   )
	EVT_MOTION   ( wxNewSashLayoutWindow::OnMotion   )
	EVT_RIGHT_UP ( wxNewSashLayoutWindow::OnRightUp  )
	EVT_SIZE     ( wxNewSashLayoutWindow::OnSize     )

END_EVENT_TABLE()

wxNewSashLayoutWindow::wxNewSashLayoutWindow( wxWindow* parent, wxWindowID id, 
											  const wxPoint& pos, const wxSize& size, 
											  long style, const wxString& name )

	: wxSashLayoutWindow( parent, id, pos, size, style, name ),
	  mStyleFlags( style ),
	  mGhostDrawn( FALSE ),
	  mDragStarted( FALSE ),
	  mButtonDragStarted( FALSE ),
	  mPressed( FALSE ),
	  mGhostRectBorderWidth( 6 ),
	  mMinOverlap( 2 )
{
}

void wxNewSashLayoutWindow::HandleSashDrag( wxSashEvent& event )
{
	wxRect dragRect = event.GetDragRect();

	switch ( GetAlignment() )
	{
		case wxLAYOUT_TOP :
		{
			SetDefaultSize( wxSize( 2000, dragRect.height) );
			break;
		}
		case wxLAYOUT_BOTTOM :
		{
			SetDefaultSize( wxSize( 2000, dragRect.height) );
			break;
		}
		case wxLAYOUT_LEFT :
		{
			SetDefaultSize( wxSize( dragRect.width, 2000 ) );
			break;
		}
		case wxLAYOUT_RIGHT :
		{
			SetDefaultSize( wxSize( dragRect.width, 2000 ) );
			break;
		}

		default: break;
	}

	RelayoutParent();
}

void wxNewSashLayoutWindow::OnPaint( wxPaintEvent& event )
{
	wxSashLayoutWindow::OnPaint( event );

	wxClientDC dc( this );

	DrawDecorations( dc );
}

void wxNewSashLayoutWindow::OnLeftDown( wxMouseEvent& event )
{
	wxPoint mousePos = wxPoint( event.GetX(), event.GetY() );

	if ( !RectContains( GetSashlessRect(), mousePos ) || mDragStarted )
	{
		event.Skip();
		return;
	}

	if ( HasBox() )
	{
		wxRect r = GetInnerRect();

		if ( RectContains( CalcBoxArea( r ), mousePos ) )
		{
			this->CaptureMouse();

			mButtonDragStarted = TRUE;
			mPressed = TRUE;
			wxClientDC dc( this );
			DrawDecorations( dc );

			return;
		}
	}

	mDragStarted = TRUE;

	mRelativeOrigin = mousePos;
	mDragOrigin = ToScreen( mRelativeOrigin );
	mGhostDrawn = FALSE;

	mCurDragAlignment = this->GetAlignment();
	mCurGhostSize = this->GetClientSize();

	TrackGhostRect( event );

	this->SetCursor( wxCURSOR_SIZING  );
	this->CaptureMouse();
}

void wxNewSashLayoutWindow::OnLeftUp( wxMouseEvent& event )
{
	if ( mDragStarted )
	{
		HideGhostRect();
		this->ReleaseMouse();
		this->SetCursor( wxCURSOR_ARROW );

		if ( mCurDragAlignment != GetAlignment() )
		{
			this->SetDefaultSize( mCurGhostSize );

			ChangeEdgePosition( (wxLayoutAlignment)mCurDragAlignment );

			RelayoutParent();
		}

		mDragStarted = FALSE;
	}
	else
	if ( mButtonDragStarted )
	{
		this->ReleaseMouse();

		wxRect r = GetInnerRect();
		wxPoint mousePos = wxPoint( event.GetX(), event.GetY() );
		mPressed = RectContains( CalcBoxArea( r ), mousePos );

		wxClientDC dc( this );
		DrawDecorations( dc );
		mButtonDragStarted = FALSE;

		if ( mPressed )	
		{	
			Show( FALSE );
			mPressed = FALSE;
			RelayoutParent();
		}
	}
	else
		event.Skip();
}

void wxNewSashLayoutWindow::OnMotion( wxMouseEvent& event )
{
	if ( mDragStarted )
	{
		TrackGhostRect( event );

		wxPoint mousePos = ToScreen( wxPoint( event.GetX(), event.GetY() ) );

		int newEdge = -1; bool hitsMouse = FALSE;

		FindNearestEdge( newEdge, mousePos, hitsMouse );

		if ( newEdge != -1 && newEdge != mCurDragAlignment  )

			if ( hitsMouse )
		{
			//wxMessageBox( "Orienation changed!" );
			// changing Alignment of ghost-rect!

			wxRect aligned = GetAlignedRect( newEdge );

			mCurDragAlignment = newEdge;

			mCurGhostSize.x = aligned.width;
			mCurGhostSize.y = aligned.height;

			mRelativeOrigin.x = mousePos.x - aligned.x;
			mRelativeOrigin.y = mousePos.y - aligned.y;

			TrackGhostRect( event );
		}
	}
	else
	if ( mButtonDragStarted )
	{
		wxRect r = GetInnerRect();

		wxPoint mousePos = wxPoint( event.GetX(), event.GetY() );
		mPressed = RectContains( CalcBoxArea( r ), mousePos );
		wxClientDC dc( this );
		DrawDecorations( dc );
	}
	else
		event.Skip();
}

void wxNewSashLayoutWindow::OnRightUp( wxMouseEvent& event )
{
}

void wxNewSashLayoutWindow::OnSize( wxSizeEvent& event )
{
	//wxSashLayoutWindow::OnSize( event );

	wxNode* pNode = GetChildren().First();

	wxWindow* pChild = pNode ? (wxWindow*)pNode->GetData() : NULL;

	if ( pChild )
	{
		wxRect r = GetInnerRect();

		if ( HasBox() || HasDragHint() )
		{
			wxSize bsz = GetBoxSize();
			int width = wxMax( bsz.x, GetDragHintWidth() );

			if ( IsVertical() )
			{
				r.y += width + SASH_MARGIN;
				r.height -= width + SASH_MARGIN;
			}
			else
			{
				r.x += width + SASH_MARGIN;
				r.width -= width + SASH_MARGIN;
			}
		}

		pChild->SetSize( r.x, r.y, r.width, r.height );
	}
}

/*** protected methods ***/

void wxNewSashLayoutWindow::TrackGhostRect( wxMouseEvent& event )
{
	wxScreenDC dc;
	dc.StartDrawingOnTop( GetParent() );

	wxPoint pos = ToScreen( wxPoint( event.GetX(), event.GetY() ) );

	wxSize clntSize = GetClientSize();

	if ( mGhostDrawn )

		DrawGhostRect( dc, mPrevGhostRect ); // erase previous one

	wxRect area( pos.x - mRelativeOrigin.x,
				 pos.y - mRelativeOrigin.y,
				 mCurGhostSize.x, mCurGhostSize.y );

	mCurGhostRect  = area;

	DrawGhostRect( dc, area ); // erase previous one

	mPrevGhostRect = area; mGhostDrawn = TRUE;

	dc.EndDrawingOnTop();
}

void wxNewSashLayoutWindow::HideGhostRect()
{
	if ( mGhostDrawn )
	{
		wxScreenDC dc;
		dc.StartDrawingOnTop( GetParent() );

		DrawGhostRect( dc, mPrevGhostRect ); // erase previous one
		mGhostDrawn = FALSE;

		dc.EndDrawingOnTop();
	}
}

void wxNewSashLayoutWindow::DrawBox( wxDC& dc, const wxRect& area )
{
	int x = area.x, y = area.y;

	/*** ripped from wxFrameLayout contrib. ("toolwnd.cpp:850") ***/

	dc.SetPen( *wxTRANSPARENT_PEN );

	dc.SetBrush( *wxLIGHT_GREY_BRUSH );

	dc.DrawRectangle( x + 1, y + 1, BTN_BOX_WIDTH - 2, BTN_BOX_HEIGHT - 2 );

	// "hard-code" metafile

	if ( !mPressed )

		dc.SetPen( *wxWHITE_PEN );
	else
		dc.SetPen( *wxBLACK_PEN );

	dc.DrawLine( x, y, x + BTN_BOX_WIDTH, y );
	dc.DrawLine( x, y, x, y + BTN_BOX_HEIGHT );

	dc.SetPen( *wxGREY_PEN );

	if ( !mPressed )
	{
		dc.DrawLine( x + 1, y + BTN_BOX_HEIGHT - 2, 
					 x + BTN_BOX_WIDTH - 1, y + BTN_BOX_HEIGHT - 2 );
		
		dc.DrawLine( x + BTN_BOX_WIDTH - 2, y + 1, 
					 x + BTN_BOX_WIDTH - 2, y + BTN_BOX_HEIGHT - 1 );
	}
	else
	{
		dc.DrawLine( x + 1, y + 1, 
			         x + BTN_BOX_WIDTH - 2, y + 1 );
					 
		dc.DrawLine( x + 1, y + 1,
			         x + 1, y + BTN_BOX_HEIGHT - 2 );
	}

	if ( !mPressed )

		dc.SetPen( *wxBLACK_PEN );
	else
		dc.SetPen( *wxWHITE_PEN );

	dc.DrawLine( x, y + BTN_BOX_HEIGHT - 1,  
		         x + BTN_BOX_WIDTH, y + BTN_BOX_HEIGHT - 1 );

	dc.DrawLine( x + BTN_BOX_WIDTH - 1, y ,
		         x + BTN_BOX_WIDTH - 1, y + BTN_BOX_HEIGHT );


#ifdef __WXGTK__

    wxPen pen( wxColour( 64,64,64 ) ,1, wxSOLID );
    
    dc.SetPen( pen );
    
    int width = BTN_BOX_WIDTH - 7;
    
    int xOfs = (mPressed) ? 4 : 3;
    int yOfs = (mPressed) ? 4 : 3;	

    int one = 1;
    for( int i = 0; i != BTN_X_WIEGHT; ++i )
    {
        dc.DrawLine( x + xOfs + i - one,
                     y + yOfs - one,
                     x + xOfs + i + width,
                     y + yOfs + width  + one);
    
        dc.DrawLine( x + xOfs + i + width ,
                     y + yOfs - one - one,
                     x + xOfs + i - one,
                     y + yOfs + width );
    }
    
#else

	dc.SetPen( *wxBLACK_PEN );

	int width = BTN_BOX_WIDTH - 7;

	int xOfs = (mPressed) ? 4 : 3;
	int yOfs = (mPressed) ? 4 : 3;

	for( int i = 0; i != BTN_X_WIEGHT; ++i )
	{
		dc.DrawLine( x + xOfs + i,
			         y + yOfs,
					 x + xOfs + i + width,
					 y + yOfs + width );

		dc.DrawLine( x + xOfs + i + width - 1,
			         y + yOfs,
					 x + xOfs + i - 1,
					 y + yOfs + width );
	}

#endif

}

void wxNewSashLayoutWindow::DrawDragHint( wxDC& dc, const wxRect& area )
{

	int ofs = 0;
	for( int i = 0; i != GROOVE_COUNT; ++i, ofs += ( GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP ) )

		if ( IsVertical() )
		{
			int x = area.x, y = area.y, length = area.width;

			dc.SetPen( *wxWHITE_PEN );
			dc.DrawLine( x, y + ofs, x + length - 1, y + ofs );
			dc.DrawPoint( x, y + ofs + 1 );

			dc.SetPen( *wxGREY_PEN );
			dc.DrawLine( x, y + ofs + 2, x + length, y + ofs + 2 );
			dc.DrawPoint( x + length - 1, y + ofs + 1 );
			dc.DrawPoint( x + length - 1, y + ofs );
		}
		else
		{
			int x = area.x, y = area.y, length = area.height;

			dc.SetPen( *wxWHITE_PEN );
			dc.DrawLine( x + ofs, y, x + ofs, y + length - 1 );
			dc.DrawPoint( x + ofs + 1, y );

			dc.SetPen( *wxGREY_PEN );
			dc.DrawLine( x + ofs + 2, y, x + ofs + 2, y + length );
			dc.DrawPoint( x + ofs + 1, y + length - 1 );
			dc.DrawPoint( x + ofs,     y + length - 1 );
		}

	/*
	dc.SetBrush( *wxWHITE_BRUSH );
	dc.DrawRectangle( area );
	*/
}

// this is ripped from wxFrameLayout contrib ("bardragpl.cpp:820")

#define _A  0xAA
#define _B  0x00
#define _C  0x55
#define _D  0x00

// FOR NOW:: static

static const unsigned char _gCheckerImg[16] = { _A,_B,_C,_D,
											    _A,_B,_C,_D,
											    _A,_B,_C,_D,
											    _A,_B,_C,_D
											  };

void wxNewSashLayoutWindow::DrawGhostRect( wxDC& dc, const wxRect& area, bool isInversed )
{
	dc.SetLogicalFunction( wxXOR );

	// this is ripped from wxFrameLayout contrib ("bardragpl.cpp:855")

	wxBitmap checker( (const char*)_gCheckerImg, 8,8 );

	wxBrush checkerBrush( checker );

	dc.SetPen( *wxTRANSPARENT_PEN );
	dc.SetBrush( checkerBrush );

	int half = mGhostRectBorderWidth / 2;

	dc.DrawRectangle( area.x - half, area.y - half,
			                area.width + 2*half, mGhostRectBorderWidth );

	dc.DrawRectangle( area.x - half, area.y + area.height - half,
			                area.width + 2*half, mGhostRectBorderWidth );

	dc.DrawRectangle( area.x - half, area.y + half - 1,
			                mGhostRectBorderWidth, area.height - 2*half + 2);

	dc.DrawRectangle( area.x + area.width - half,
							area.y + half - 1,
			                mGhostRectBorderWidth, area.height - 2*half + 2);

	dc.SetBrush( wxNullBrush );
}

int wxNewSashLayoutWindow::GetHintWidth()
{
	return 10;
}

wxSize wxNewSashLayoutWindow::GetBoxSize()
{
	return wxSize( BTN_BOX_WIDTH, BTN_BOX_HEIGHT );
}

int wxNewSashLayoutWindow::GetDragHintWidth()
{
	return DRAG_HIND_WIDTH;
}

wxRect wxNewSashLayoutWindow::CalcBoxArea( const wxRect& innerRect )
{
	wxSize bsz = GetBoxSize();

	int width = wxMax( bsz.x, GetDragHintWidth() );

	if ( IsVertical() )
	
		return wxRect( innerRect.x + innerRect.width - SASH_MARGIN - bsz.x,
					   innerRect.y, bsz.x, bsz.y );
	else
		return wxRect( innerRect.x, innerRect.y, bsz.x, bsz.y );
}

wxRect wxNewSashLayoutWindow::CalcDragHintArea( const wxRect& innerRect )
{
	wxSize bsz = GetBoxSize();
	int hintWidth = GetDragHintWidth();

	int width = wxMax( bsz.x, hintWidth );

	if ( IsVertical() )

		return wxRect( innerRect.x + SASH_MARGIN, innerRect.y + (width - hintWidth)/2, 
					   HasBox() ? innerRect.width - SASH_MARGIN*3 - bsz.x
								: innerRect.width - SASH_MARGIN*2, hintWidth );
	else
	{
		int topSpace = HasBox() ? bsz.y + SASH_MARGIN*2 : SASH_MARGIN;

		return wxRect( innerRect.x + (width - hintWidth)/2, innerRect.y + topSpace,
					   hintWidth, innerRect.height - topSpace - SASH_MARGIN );
	}
}

void wxNewSashLayoutWindow::DrawDecorations( wxDC& dc )
{
	wxRect r = GetInnerRect();

	if ( HasBox() ) DrawBox( dc, CalcBoxArea( r ) );
	if ( HasDragHint() ) DrawDragHint( dc, CalcDragHintArea( r ) );
}

// utilities

wxRect wxNewSashLayoutWindow::GetSashlessRect()
{
	int w = 0, h = 0, x = 0, y = 0;
	GetClientSize( &w, &h );

	// FIXME:: how can i get this width??
	#define SASH_WIDTH 5

	if ( GetSashVisible( wxSASH_TOP    ) ) { y += SASH_WIDTH; h -= SASH_WIDTH; }
	if ( GetSashVisible( wxSASH_BOTTOM ) ) { h -= SASH_WIDTH; }
	if ( GetSashVisible( wxSASH_LEFT   ) ) { x += SASH_WIDTH; w -= SASH_WIDTH; }
	if ( GetSashVisible(  wxSASH_RIGHT ) ) { w -= SASH_WIDTH; }

	return wxRect( x,y, w,h );
}

wxRect wxNewSashLayoutWindow::GetInnerRect()
{
	wxRect r = GetSashlessRect();

	int extra = GetExtraBorderSize();

	r.width  -= 2*extra;
	r.height -= 2*extra;
	r.x += extra;
	r.y += extra;

	if ( IsVertical() )
	{
		r.y += SASH_MARGIN;
		r.height -= SASH_MARGIN*2;
	}
	else
	{
		r.x += SASH_MARGIN;
		r.width -= SASH_MARGIN*2;
	}

	return r;
}

bool wxNewSashLayoutWindow::HasBox()
{
	return ((mStyleFlags & wxSW_CLOSE_BOX) != 0);
}

bool wxNewSashLayoutWindow::HasDragHint()
{
	return ((mStyleFlags & wxSW_DRAG_HINT) != 0);
}

bool wxNewSashLayoutWindow::CanBeDragged()
{
	return !( mStyleFlags & wxSW_NO_DRAG );
}

bool wxNewSashLayoutWindow::IsVertical()
{
	return GetAlignment() == wxLAYOUT_LEFT ||
		   GetAlignment() == wxLAYOUT_RIGHT;
}

wxPoint wxNewSashLayoutWindow::ToScreen( const wxPoint& localPoint )
{
	int x = localPoint.x, y = localPoint.y;
	this->ClientToScreen( &x, &y );

	return wxPoint( x, y );
}

wxRect wxNewSashLayoutWindow::GetParentRect()
{
	int x = 0, y = 0;

	this->GetParent()->ClientToScreen( &x, &y );

	int w = 0, h = 0;
	this->GetParent()->GetClientSize( &w, &h );

	return wxRect( x,y, w,h );
}

wxRect wxNewSashLayoutWindow::ToScreen( const wxRect& localRect )
{
	int x = localRect.x, y = localRect.y;
	this->ClientToScreen( &x, &y );

	return wxRect( x,y, localRect.width, localRect.height );
}

bool wxNewSashLayoutWindow::IsWithinDragArea( wxMouseEvent& event )
{
	// TBD::
	return TRUE;
}

wxRect wxNewSashLayoutWindow::GetAlignedRect( int edge )
{
	wxRect parentRect = GetParentRect();
	wxSize parentSz = wxSize( parentRect.width, parentRect.height );
	wxSize sz = GetClientSize();

	int width = ( GetAlignment() == wxLAYOUT_TOP ||
				  GetAlignment() == wxLAYOUT_BOTTOM ) 
				  ? sz.y : sz.x;
	wxRect r;

	switch( edge )
	{
		case wxLAYOUT_TOP    : r = wxRect( 0,0, parentSz.x, width );break;

		case wxLAYOUT_BOTTOM : r = wxRect( 0, parentSz.y - width, 
										   parentSz.x, width );break;

		case wxLAYOUT_LEFT   : r = wxRect( 0,0, width, parentSz.y );break;

		case wxLAYOUT_RIGHT  : r = wxRect( parentSz.x - width, 0, 
										   width, parentSz.y
										 );break;

		default: break;
	}

	r.x += parentRect.x;
	r.y += parentRect.y;

	return r;
}

bool wxNewSashLayoutWindow::RectContains( const wxRect& rect, 
										  const wxPoint& point )
{
	return ( point.x >= rect.x && point.x < rect.x + rect.width  ) &&
		   ( point.y >= rect.y && point.y < rect.y + rect.height );
}

bool wxNewSashLayoutWindow::TestNearestEdge( int& edge, const wxPoint& mousePos, 
											 bool& hitsMouse, int rqEdge )
{
	wxSize sz = GetClientSize();

	int width = ( GetAlignment() == wxLAYOUT_TOP ||
				  GetAlignment() == wxLAYOUT_BOTTOM ) 
				  ? sz.y : sz.x;

	wxRect parentRect = GetParentRect();

	switch( rqEdge )
	{
		case wxLAYOUT_TOP : 
			{
				if ( mCurGhostRect.y + mMinOverlap < parentRect.y )	
				{					
					edge = wxLAYOUT_TOP;

					hitsMouse = mousePos.y + mMinOverlap < parentRect.y + width;
				}

				break;
			}
		case wxLAYOUT_BOTTOM : 
			{
				if ( mCurGhostRect.y + mCurGhostRect.height - mMinOverlap > 
					 parentRect.y + parentRect.height )	
				{
					edge = wxLAYOUT_BOTTOM;

					hitsMouse = mousePos.y - mMinOverlap > 
								parentRect.y + parentRect.height - width;
				}

				break;
			}
		case wxLAYOUT_LEFT : 
			{
				if ( mCurGhostRect.x + mMinOverlap < parentRect.x )	
				{					
					edge = wxLAYOUT_LEFT;

					hitsMouse = mousePos.x + mMinOverlap < parentRect.x + width;
				}

				break;
			}
		case wxLAYOUT_RIGHT : 
			{
				if ( mCurGhostRect.x + mCurGhostRect.width - mMinOverlap > 
					 parentRect.x + parentRect.width )	
				{	
					edge = wxLAYOUT_RIGHT;

					hitsMouse = mousePos.x - mMinOverlap > 
								parentRect.x + parentRect.width - width;
				}

				break;
			}
		default: break;
	}

	return edge == rqEdge && hitsMouse;
}

void wxNewSashLayoutWindow::FindNearestEdge( int& edge, 
											 const wxPoint& mousePos, 
											 bool& hitsMouse )
{
	hitsMouse = FALSE;
	edge = -1; // not found initially

	if ( TestNearestEdge( edge, mousePos, hitsMouse, wxLAYOUT_TOP    ) ) return;
	if ( TestNearestEdge( edge, mousePos, hitsMouse, wxLAYOUT_BOTTOM ) ) return;
	if ( TestNearestEdge( edge, mousePos, hitsMouse, wxLAYOUT_LEFT   ) ) return;
	if ( TestNearestEdge( edge, mousePos, hitsMouse, wxLAYOUT_RIGHT  ) ) return;
}

void wxNewSashLayoutWindow::ChangeEdgePosition( wxLayoutAlignment align )
{
	this->SetSashVisible( wxSASH_BOTTOM, FALSE );
	this->SetSashVisible( wxSASH_TOP,    FALSE );
	this->SetSashVisible( wxSASH_RIGHT,  FALSE );
	this->SetSashVisible( wxSASH_LEFT,   FALSE );

	switch( align )
	{
		case wxLAYOUT_TOP    : this->SetSashVisible( wxSASH_BOTTOM,   TRUE );break;
		case wxLAYOUT_BOTTOM : this->SetSashVisible( wxSASH_TOP,  TRUE );break;
		case wxLAYOUT_LEFT   : this->SetSashVisible( wxSASH_RIGHT,  TRUE );break;
		case wxLAYOUT_RIGHT  : this->SetSashVisible( wxSASH_LEFT, TRUE );break;
		default : break;
	}

	if ( align == wxLAYOUT_TOP ||
		 align == wxLAYOUT_BOTTOM )

		this->SetOrientation( wxLAYOUT_HORIZONTAL );
	else
		this->SetOrientation( wxLAYOUT_VERTICAL );

	this->SetAlignment( align );
}


void wxNewSashLayoutWindow::RelayoutParent()
{
	if ( GetParent()->IsKindOf( CLASSINFO(wxMDIParentFrame) ) )
	{
		wxMDIParentFrame* pParent = (wxMDIParentFrame*)GetParent();

		wxLayoutAlgorithm alg;
		alg.LayoutMDIFrame( (wxMDIParentFrame*)GetParent() );

		pParent->GetClientWindow()->Refresh(); 
											   
	}
	else
	{
		wxLayoutAlgorithm alg;
		alg.LayoutWindow( GetParent() );
	}

	// HACK:: otherwise some trash is left on the client-area
	//        and surrounding windows

	wxNode* pNode = GetParent()->GetChildren().First();

	while( pNode )
	{
		((wxWindow*)pNode->GetData())->Refresh();

		pNode = pNode->GetNext();
	}
}
