#ifndef K3DUI_ORIENTATION_H
#define K3DUI_ORIENTATION_H

// K-3D
// Copyright (c) 1995-2004, Timothy M. Shead
//
// Contact: tshead@k-3d.com
//
// 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 2 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, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

/** \file
		\author Tim Shead (tshead@k-3d.com)
*/

#include "k3dcontrol.h"

#include <k3dsdk/algebra.h>
#include <k3dsdk/vectors.h>

// Forward declarations
class sdpGtkIObjectContainer;
class sdpGtkEvent;

namespace k3d
{

// Forward declarations
class idocument;
class iproperty;
class istate_recorder;

namespace orientation
{

/////////////////////////////////////////////////////////////////////////////
// idata_proxy

/// Abstract interface for an object that proxies a data source for a orientation control (i.e. the "model" in model-view-controller)
class idata_proxy
{
public:
	virtual ~idata_proxy() {}

	/// Called to return the underlying data value
	virtual const angle_axis value() = 0;
	/// Called to set a new data value
	virtual void set_value(const angle_axis& Value) = 0;
	/// Signal emitted if the underlying data changes
	typedef SigC::Signal0<void> changed_signal_t;
	/// Signal emitted if the underlying data changes
	virtual changed_signal_t& changed_signal() = 0;

protected:
	idata_proxy() {}
	idata_proxy(const idata_proxy& RHS) {}
	idata_proxy& operator=(const idata_proxy& RHS) { return *this; }
};

/////////////////////////////////////////////////////////////////////////////
// proxy

/// Convenience factory function for creating k3d::spin_button::idata_proxy objects, specialized for k3d::iproperty
std::auto_ptr<idata_proxy> proxy(iproperty& Data);

/////////////////////////////////////////////////////////////////////////////
// control

/// Provides a UI for modifying the orientation of an object
class control :
	public k3dControl
{
	typedef k3dControl base;

public:
	control(k3d::iunknown* CommandNodeParent, std::string CommandNodeName);
	~control();

	/// Called by the framework when instantiating the button from a GTKML (XML) document
	bool Create(sdpGtkIObjectContainer* ObjectContainer, sdpxml::Document& Document, sdpxml::Element& Element);

	/// Attaches the button to the object it fronts for
	bool attach(std::auto_ptr<idata_proxy> Data, k3d::idocument& Document, k3d::istate_recorder* const StateRecorder, std::string StateChangeName);

	const std::string CustomType() const;

private:
	/// Called to handle SDPGTK events
	void OnEvent(sdpGtkEvent* Event);

	/// Called when the GTK+ widgets are about to disappear
	void on_destroy();
	/// Called to reset the object orientation to resting position
	void on_reset();

	/// Stores a reference to the owning document object
	idocument* m_document;
	/// Stores a reference to the underlying data object
	std::auto_ptr<idata_proxy> m_data;
};

} // namespace orientation

} // namespace k3d

#endif // K3DUI_ORIENTATION_H

