// 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
		\brief Implements the k3dObjectDialog class, which provides a standard dialog implementation for K-3D objects
		\author Tim Shead (tshead@k-3d.com)
*/

#include "k3dobjectdialog.h"

#include <k3dsdk/application.h>
#include <k3dsdk/imouse_event_observer.h>
#include <k3dsdk/idocument.h>
#include <k3dsdk/iobject_collection.h>
#include <k3dsdk/iobject.h>
#include <k3dsdk/objects.h>
#include <k3dsdk/ioptions.h>
#include <k3dsdk/selection.h>
#include <k3dsdk/utility.h>
#include <k3dsdk/viewport.h>

#include <sdpgtk/sdpgtkevents.h>

namespace
{

const std::string control_ok = "ok";
const std::string control_close = "close";

} // namespace

/////////////////////////////////////////////////////////////////////////////
// k3dObjectDialog

k3dObjectDialog::k3dObjectDialog(k3d::iobject& Object, const bool GrabMouseFocus, const bool AutoDestroy, const bool ShowObjectName, const std::string& CommandNodeName, k3d::window_geometry_store* const GeometryStore) :
	base(&Object, CommandNodeName, GeometryStore),
	m_object(Object),
	m_AutoDestroy(AutoDestroy),
	m_ShowObjectName(ShowObjectName)
{
	// We want to be notified if the owning object is deleted
	m_object.deleted_signal().connect(SigC::slot(*this, &k3dObjectDialog::on_object_deleted));
	// We want to be notified if the owning object is renamed
	m_object.name_changed_signal().connect(SigC::slot(*this, &k3dObjectDialog::on_object_renamed));

	if(GrabMouseFocus)
		{
			k3d::set_mouse_focus(m_object.document(), m_object);
			k3d::viewport::redraw_all(m_object.document(), k3d::iviewport::ASYNCHRONOUS);
		}
}

bool k3dObjectDialog::LoadGTKMLTemplate(const boost::filesystem::path& Template)
{
	// Load the template ...
	return_val_if_fail(base::LoadGTKMLTemplate(Template), false);

	// Update the titlebar ...
	if(m_ShowObjectName)
		on_object_renamed();

	return true;
}

k3dObjectDialog::~k3dObjectDialog()
{
}

/////////////////////////////////////////////////////////////////////////////
// k3d::icommand_node implementation

bool k3dObjectDialog::execute_command(const std::string& Command, const std::string& Arguments)
{
	if(Command == control_ok)
		{
			return InteractiveActivateButton(control_ok, k3d::application().options().tutorial_speed(), true);
		}
	else if(Command == control_close)
		{
			return InteractiveActivateButton(control_close, k3d::application().options().tutorial_speed(), true);
		}

	return base::execute_command(Command, Arguments);
}

// We have an unfortunate clash with X ...
#ifdef RootWindow
#undef RootWindow
#endif // RootWindow

void k3dObjectDialog::on_object_deleted()
{
	ObjectDeleted();
}

void k3dObjectDialog::on_object_renamed()
{
	// If we're not open, we're done ...
	return_if_fail(Root());

	RootWindow().SetTitle(m_object.name().c_str());
}

void k3dObjectDialog::ObjectDeleted()
{
	// Since the object is already going away, we don't need to destroy it ourselves ...
	m_AutoDestroy = false;
	delete this;
}

void k3dObjectDialog::OnOK()
{
	// Record this as a user action ...
	k3d::record_command(*this, k3d::icommand_node::command_t::USER_INTERFACE, control_ok);
	base::OnOK();
}

void k3dObjectDialog::OnClose()
{
	// Record this as a user action ...
	k3d::record_command(*this, k3d::icommand_node::command_t::USER_INTERFACE, control_close);
	base::OnClose();
}

void k3dObjectDialog::CloseDialog()
{
	// If AutoDestroy is enabled, kill our owning object (we'll be notified and destroy ourselves, so override the default implementation)
	if(m_AutoDestroy)
		k3d::delete_objects(m_object.document(), k3d::make_collection<k3d::objects_t>(&m_object));
	else
		base::CloseDialog();
}


