//
// C++ Implementation: QuaternionAdapter
//
// Description:
//
//
// Author: Erik Ogenvik <erik@ogenvik.org>, (C) 2006
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.//
//
#include "QuaternionAdapter.h"
#include "Widget.h"

#include <CEGUI/Window.h>
#include <OgreStringConverter.h>


namespace Ember::OgreView::Gui {

QuaternionAdapter::QuaternionAdapter(CEGUI::Window* degreeWindow, CEGUI::Window* xWindow, CEGUI::Window* yWindow, CEGUI::Window* zWindow, const Ogre::Quaternion& quaternion)
		: mQuaternion(quaternion), mOriginalQuaternion(quaternion), mVectorAdapter(xWindow, yWindow, zWindow), mDegreeWindow(degreeWindow), mSelfUpdate(false) {
	if (degreeWindow) {
		degreeWindow->subscribeEvent(CEGUI::Window::EventTextChanged, CEGUI::Event::Subscriber(&QuaternionAdapter::window_TextChanged, this));
	}
	mVectorAdapter.EventValueChanged.connect(sigc::mem_fun(*this, &QuaternionAdapter::vectorAdapter_ValueChanged));

}

QuaternionAdapter::~QuaternionAdapter() = default;

void QuaternionAdapter::setValue(const Ogre::Quaternion& quaternion) {
	updateGui(quaternion);
	EventValueChanged.emit();
}


const Ogre::Quaternion& QuaternionAdapter::getValue() const {
	const Ogre::Vector3& axis = mVectorAdapter.getValue();
	float degrees = 0;
	if (mDegreeWindow) {
		degrees = Ogre::StringConverter::parseReal(mDegreeWindow->getText().c_str());
	}

	mQuaternion.FromAngleAxis(Ogre::Degree(degrees), axis);
	return mQuaternion;
}

const Ogre::Quaternion& QuaternionAdapter::getOriginalValue() const {
	return mOriginalQuaternion;
}

void QuaternionAdapter::updateGui(const Ogre::Quaternion& quaternion) {
	mSelfUpdate = true;

	if (!quaternion.isNaN()) {
		Ogre::Vector3 axis;
		Ogre::Degree angle;
		quaternion.ToAngleAxis(angle, axis);
		mVectorAdapter.updateGui(axis);
		if (mDegreeWindow) {
			mDegreeWindow->setText(Ogre::StringConverter::toString(angle.valueDegrees()));
		}
	} else {
		mVectorAdapter.updateGui(Ogre::Vector3::ZERO);
		if (mDegreeWindow) {
			mDegreeWindow->setText("");
		}
	}
	mSelfUpdate = false;
}

bool QuaternionAdapter::window_TextChanged(const CEGUI::EventArgs& e) {
	if (!mSelfUpdate) {
		EventValueChanged.emit();
	}
	return true;
}

void QuaternionAdapter::vectorAdapter_ValueChanged() {
	if (!mSelfUpdate) {
		EventValueChanged.emit();
	}
}

}



