/////////////////////////////////////////////////////////////////////////////
// Name:        collapsiblepanel.cpp
// Purpose:     
// Author:      César Mauri Loba
// Modified by: 
// Created:     01/06/2011 18:17:58
// RCS-ID:      
// Copyright:   (C) 2011 Cesar Mauri Loba - CREA Software Systems
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.    
/////////////////////////////////////////////////////////////////////////////
// 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

////@begin includes
////@end includes

#include "collapsible.h"

////@begin XPM images
////@end XPM images

using namespace spcore;
using namespace boost;
using namespace std;

namespace mod_widgets {

CollapsibleComponent::CollapsibleComponent(const char * name, int argc, const char * argv[])
: CComponentAdapter(name, argc, argv)
, m_panel(NULL)
{
	//
	// Create pins and storage
	//
	m_oPinExpanded= CTypeBool::CreateOutputPin("expanded");
	RegisterOutputPin (*m_oPinExpanded);
	
	m_expanded= CTypeBool::CreateInstance();

	//
	// Process arguments
	//
	if (argc) {
		for (int i= 0; i< argc; ++i) {
			if (strcmp ("-l", argv[i])== 0) {
				// Label
				++i;

				if (i== argc) throw std::runtime_error("widget_collapsible. Missing value for -l argument");
				m_label= argv[i];
			}			
			else if (strlen(argv[i])) {
				string error_msg("widget_collapsible. Unknown option:");
				error_msg+= argv[i];
				throw std::runtime_error(error_msg);
			}
		}
	}
}

int CollapsibleComponent::DoInitialize()
{
	m_oPinExpanded->Send(m_expanded);
	return 0;
}

// 
// Private methods
//	

wxWindow* CollapsibleComponent::GetGUI(wxWindow * parent) {
	assert (wxIsMainThread());
	if (m_panel) {
		// Already created
		assert (false);
		getSpCoreRuntime()->LogMessage(ICoreRuntime::LOG_ERROR, "panel alredy open", "collapsible");
		return NULL;
	}
	else {
		m_panel= new CollapsiblePanel();
		m_panel->SetComponent(this);
		m_panel->Create(parent);
	}

	return m_panel;
}

// 
// Called from GUI
//	
void CollapsibleComponent::SetIsExpanded(bool v)
{
	if (m_expanded->getValue()!= v) {
		m_expanded->setValue(v);
		m_oPinExpanded->Send(m_expanded);
	}
}

void CollapsibleComponent::OnPanelDestroyed ()
{
	assert (wxIsMainThread());
	m_panel= NULL;
}

CollapsibleComponent::~CollapsibleComponent()
{
	assert (wxIsMainThread());
	if (m_panel) {
		m_panel->SetComponent(NULL);
		m_panel->Close();
		m_panel= NULL;
	}
}

//////////////////////////////////////////////////////////////////////////////


/*!
 * CollapsiblePanel type definition
 */

IMPLEMENT_DYNAMIC_CLASS( CollapsiblePanel, wxGenericCollapsiblePane )


/*!
 * CollapsiblePanel event table definition
 */

BEGIN_EVENT_TABLE( CollapsiblePanel, wxGenericCollapsiblePane )

////@begin CollapsiblePanel event table entries
    EVT_COLLAPSIBLEPANE_CHANGED( ID_COLLAPSIBLEPANE_PANEL, CollapsiblePanel::OnCollapsiblepanePanelPaneChanged )

////@end CollapsiblePanel event table entries

END_EVENT_TABLE()


/*!
 * CollapsiblePanel constructors
 */

CollapsiblePanel::CollapsiblePanel()
{
    Init();
}

CollapsiblePanel::CollapsiblePanel(wxWindow* parent, wxWindowID id, const wxString& label, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator)
{
    Init();
    Create(parent, id, label, pos, size, style, validator);
}


/*!
 * CollapsiblePanel creator
 */

bool CollapsiblePanel::Create(wxWindow* parent, wxWindowID id, const wxString& label, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator)
{
////@begin CollapsiblePanel creation
    wxGenericCollapsiblePane::Create(parent, id, label, pos, size, style, validator);
    CreateControls();
////@end CollapsiblePanel creation
    return true;
}


/*!
 * CollapsiblePanel destructor
 */

CollapsiblePanel::~CollapsiblePanel()
{
	if (m_component!= NULL) {
		m_component->OnPanelDestroyed();
		m_component= NULL;
	}
////@begin CollapsiblePanel destruction
////@end CollapsiblePanel destruction
}


/*!
 * Member initialisation
 */

void CollapsiblePanel::Init()
{
	m_component= NULL;
////@begin CollapsiblePanel member initialisation
////@end CollapsiblePanel member initialisation
}


/*!
 * Control creation for CollapsiblePanel
 */

void CollapsiblePanel::CreateControls()
{    
////@begin CollapsiblePanel content construction
////@end CollapsiblePanel content construction
	if (m_component->GetLabel().size()) {
		wxString label(m_component->GetLabel().c_str(), wxConvUTF8);
		this->SetLabel(label);
	}
}


/*!
 * wxEVT_COMMAND_COLLPANE_CHANGED event handler for ID_COLLAPSIBLEPANE_PANEL
 */

void CollapsiblePanel::OnCollapsiblepanePanelPaneChanged( wxCollapsiblePaneEvent& event )
{
	if (GetParent()) {
		wxSizeEvent ev;
		wxPostEvent (GetParent(), ev);
	}
	m_component->SetIsExpanded(!event.GetCollapsed());
    event.Skip(false);
}


/*!
 * Should we show tooltips?
 */

bool CollapsiblePanel::ShowToolTips()
{
    return true;
}

/*!
 * Get bitmap resources
 */

wxBitmap CollapsiblePanel::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin CollapsiblePanel bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end CollapsiblePanel bitmap retrieval
}

/*!
 * Get icon resources
 */

wxIcon CollapsiblePanel::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin CollapsiblePanel icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end CollapsiblePanel icon retrieval
}

}; // namespace
