/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: pm_flalg.cpp,v 1.1 2001/04/03 20:10:27 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
    #pragma implementation "pm_flmgr.cpp"
    #pragma interface "pm_flmgr.cpp"
#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/pm_flalg.h"

// FL-stuff
#include "wx/fl/controlbar.h"
#include "wx/fl/barhintspl.h"
#include "wx/fl/cbcustom.h"
#include "wx/fl/updatesmgr.h"

#include "wx/pmf/pm.h" // import wxPMBootStrapService

/***** Implementation for class wxPMFrameLayoutPreferenceTemplate *****/

wxPMFrameLayoutPreferenceTemplate::wxPMFrameLayoutPreferenceTemplate( 
									wxClassInfo* pPaneClass,
								    wxPMFrameLayoutPreference* pPreference )

	: m_pPaneClass( pPaneClass ),
	  m_pPrefrence( pPreference )
{}

wxPMFrameLayoutPreferenceTemplate::~wxPMFrameLayoutPreferenceTemplate()
{
	if ( m_pPrefrence ) delete m_pPrefrence;
}

/***** Implementation for class wxPMFrameLayoutPreference *****/

IMPLEMENT_DYNAMIC_CLASS( wxPMFrameLayoutPreference, wxPMLayoutPreference )

wxPMFrameLayoutPreference::wxPMFrameLayoutPreference()
{}

wxPMFrameLayoutPreference::wxPMFrameLayoutPreference( int alignment, int xPos, int row,
													  int width, int height, bool isFixed )
	: m_Alignment( alignment ),
	  m_XPos( xPos ),
	  m_Row( row ),
	  m_Width( width ),
	  m_Height( height ),
	  m_IsFixed( isFixed )
{}

void wxPMFrameLayoutPreference::Serialize( wxConfigBase& cfg, const wxString& key, bool isLoading )
{
	// TBD::
}

/***** Implementation for class wxPMFLAlgorithm *****/

IMPLEMENT_DYNAMIC_CLASS( wxPMFLAlgorithm, wxEvtHandler )

wxPMFLAlgorithm::wxPMFLAlgorithm()

	: m_RelayoutPending( FALSE ),
	  m_NextWndId( 9000 )
{
	SetRefData( (wxObjectRefData*)(wxPMService*)this );
}

wxPMFLAlgorithm::~wxPMFLAlgorithm()
{
	SetRefData( NULL );

	WX_CLEAR_ARRAY( m_PrefTemplates );
}

wxObject* wxPMFLAlgorithm::GetWxObject()
{
	return (wxObject*)this;
}

void* wxPMFLAlgorithm::GetInterface( const char* infName, const char* version )
{
	if ( strcmp( infName, "I_PMPaneLayoutAlgorithm" ) == 0 )

		return (void*)(I_PMPaneLayoutAlgorithm*)this;
	else
		return NULL;
}

bool wxPMFLAlgorithm::Start()
{
    m_pLayout = new wxFrameLayout( wxPMBootSvc().GetMainWindow(), 
								  wxPMBootSvc().GetMainWindow()->GetClientWindow() );

   // Disables toolbars (temporary till it is working again)
	m_pLayout->EnableFloating( FALSE );

	m_pLayout->PushDefaultPlugins();
	m_pLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // fancy "X"es and bevel for bars
	m_pLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // fancy "X"es and bevel for bars
	m_pLayout->AddPlugin( CLASSINFO( cbSimpleCustomizationPlugin ) ); // popups for showing/hiding bars

	m_pLayout->SetUpdatesManager( new cbSimpleUpdatesMgr( m_pLayout ) );
	
	cbCommonPaneProperties props;
	m_pLayout->GetPaneProperties( props );
	props.mRealTimeUpdatesOn = FALSE;
	m_pLayout->SetPaneProperties( props );
	
	wxPMBootSvc().AddListener( this );

	bool ok = wxPMBootSvc().
		RegisterUniqueServiceInstance( this, "I_PMPaneLayoutAlgorithm" );

	wxASSERT_MSG( ok, "There can only be one instance of panle-layout algorithm" );

	return TRUE;
}

bool wxPMFLAlgorithm::Stop()
{
	// FIXME:: ensure ordering...

	wxPMBootSvc().RemoveListener( this );

	if ( m_pLayout ) 
        delete m_pLayout;

	return TRUE;
}

void wxPMFLAlgorithm::OnPaneShown( wxPMPane& pane )
{
	if ( pane.GetParentPane() == NULL )
	{
		//m_ActivePanes.Add( &pane );

		cbBarInfo* pBar = m_pLayout->FindBarByWindow( pane.GetPaneWindow() );

		if ( !pBar )
		{
			// default
			wxPMFrameLayoutPreference pref( FL_ALIGN_LEFT, 0, 0, 100, 180, FALSE );

			wxPMFrameLayoutPreference* pPref = 
				(wxPMFrameLayoutPreference*)pane.GetLayoutPefs();

			if ( pPref )
				pref = *pPref;

			cbDimInfo sizes( pref.m_Width, pref.m_Height, // when docked horizontally      
							 pref.m_Width, pref.m_Height,    // when docked vertically        
							 pref.m_Width, pref.m_Height, // when floated                  
							 pref.m_IsFixed,  // the bar is fixed-size
							 5,     // vertical gap (bar border)
							 5      // horizontal gap (bar border)
						   ); 

			wxWindow* pMainWnd = wxPMBootSvc().GetMainWindow();

			pane.CreatePaneWindow( pMainWnd );

			m_pLayout->AddBar( pane.GetPaneWindow(),// bar window
							   sizes, pref.m_Alignment,// alignment ( 0-top,1-bottom, etc)
							   pref.m_Row,                   // insert into 0th row (vert. position)
							   pref.m_XPos,                   // offset from the start of row (in pixels)
							   pane.GetPaneName()  // name to refer in customization pop-ups
						   );

			// TBD:: regard wxPMFrameLayoutPreference for the given pane

			m_pLayout->RecalcLayout( TRUE );
		}
		else
		{
			if ( pBar->mState == wxCBAR_HIDDEN )

				m_pLayout->InverseVisibility( pBar );
		}

	//	pane.GetPaneWindow()->Show( TRUE );
    
	//	m_RelayoutPending = TRUE;
	}
}

void wxPMFLAlgorithm::OnPaneHidden( wxPMPane& pane )
{
	if ( pane.GetParentPane() == NULL )
	{
		//m_ActivePanes.Remove( &pane );

		cbBarInfo* pBar = m_pLayout->FindBarByWindow( pane.GetPaneWindow() );

		if ( pBar->mState != wxCBAR_HIDDEN )

			m_pLayout->InverseVisibility( pBar );

	//	m_RelayoutPending = TRUE;
	}
}

void wxPMFLAlgorithm::OnServiceStarted( wxPMService& service )
{
	/*
	if ( service.GetWxObject()->IsKindOf( CLASSINFO( wxPMPane ) ) )
	{
		wxPMPane* pPane = (wxPMPane*)service.GetWxObject();

		if ( pPane->GetParentPane() == NULL )
		
			m_TopLevelPanes.Add( pPane );
	}
	*/
}

void wxPMFLAlgorithm::OnServiceStopped( wxPMService& service )
{
	/*
	if ( service.GetWxObject()->IsKindOf( CLASSINFO( wxPMPane ) ) )
	{
		wxPMPane* pPane = (wxPMPane*)service.GetWxObject();

		if ( pPane->GetParentPane() == NULL )
		
			m_TopLevelPanes.Remove( pPane );
	}
	*/
}


wxPMLayoutPreference* wxPMFLAlgorithm::CreateDefaultLayoutPrefs()
{
	return NULL;
}

void wxPMFLAlgorithm::Serialize( wxConfigBase& cfg, const wxString& key, bool isLoading )
{
}

void wxPMFLAlgorithm::AddPreferenceTemplate( wxPMFrameLayoutPreferenceTemplate* pTempl )
{
	m_PrefTemplates.Add( pTempl );
}

void wxPMFLAlgorithm::AddPreferenceTemplate( wxClassInfo* pClass, 
												    wxPMFrameLayoutPreference* pPref )
{
	m_PrefTemplates.Add( new wxPMFrameLayoutPreferenceTemplate( pClass, pPref ) );
}

wxFrameLayout* wxPMFLAlgorithm::GetFrameLayout()
{
	return m_pLayout;
}
