//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * 四要素実数カラーテスト実装
 * @author Junpee
 */

#include "Test/stdafx.h"
#include "Core/Primitive/Color4fTest.h"
#include "Core/Primitive/Color4f.h"
#include "Core/Primitive/Color3c.h"
#include "Core/Primitive/Color4c.h"
#include "Core/Primitive/Color3f.h"

//------------------------------------------------------------------------------
// コンストラクタ
Color4fTest::Color4fTest(String name) : TestCase(name){
}
//------------------------------------------------------------------------------
// テストスィートの取得
Test* Color4fTest::suite(){
	TestSuite* suite = new TestSuite("Color4fTest");
	suite->addTest(new TestCaller(Color4fTest, testConstructor));
	suite->addTest(new TestCaller(Color4fTest, testFixedNumber));
	suite->addTest(new TestCaller(Color4fTest, testSetValue));
	suite->addTest(new TestCaller(Color4fTest, testArithmetic));
	suite->addTest(new TestCaller(Color4fTest, testSubstitutionArithmetic));
	suite->addTest(new TestCaller(Color4fTest, testColorArithmetic));
	suite->addTest(new TestCaller(Color4fTest, testHSV));
	suite->addTest(new TestCaller(Color4fTest, testLogicalOperation));
	suite->addTest(new TestCaller(Color4fTest, testToString));
	return suite;
}
//------------------------------------------------------------------------------
// コンストラクタテスト
void Color4fTest::testConstructor(){
	TestEquals(16, (int)sizeof(Color4f));
	Color4f col0(0.5f, 1.f, 2.f, 0.f);
	TestEquals(0.5f, col0.r);
	TestEquals(1.f, col0.g);
	TestEquals(2.f, col0.b);
	TestEquals(0.f, col0.a);
	TestEquals(0.5f, col0.array[0]);
	TestEquals(1.f, col0.array[1]);
	TestEquals(2.f, col0.array[2]);
	TestEquals(0.f, col0.array[3]);
	Color4f col1(0.f, 1.f, 2.f);
	TestEquals(0.f, col1.r);
	TestEquals(1.f, col1.g);
	TestEquals(2.f, col1.b);
	TestEquals(1.f, col1.a);
	col1 = col0;
	TestEquals(0.5f, col1.r);
	TestEquals(1.f, col1.g);
	TestEquals(2.f, col1.b);
	TestEquals(0.f, col1.a);
	Color4f col2(Color3c(64, 128, 192));
	TestAssert(Color4f(64.f / 255.f, 128.f / 255.f, 192.f / 255.f, 1.f).
		epsilonEquals(col2, Math::epsilon));
	Color4f col3(Color4c(64, 128, 192, 64));
	TestAssert(Color4f(
		64.f / 255.f, 128.f / 255.f, 192.f / 255.f, 64.f / 255.f).
		epsilonEquals(col3, Math::epsilon));
	Color4f col4(Color3f(1.f, 2.f, 3.f));
	TestAssert(Color4f(1.f, 2.f, 3.f, 1.f) == col4);
}
//------------------------------------------------------------------------------
// 定数テスト
void Color4fTest::testFixedNumber(){
	TestAssert(Color4f(1.f, 1.f, 1.f) == Color4f::white);
	TestAssert(Color4f(0.5f, 0.5f, 0.5f) == Color4f::gray);
	TestAssert(Color4f(0.f, 0.f, 0.f) == Color4f::black);
	TestAssert(Color4f(1.f, 0.f, 0.f) == Color4f::red);
	TestAssert(Color4f(0.f, 1.f, 0.f) == Color4f::green);
	TestAssert(Color4f(0.f, 0.f, 1.f) == Color4f::blue);
	TestAssert(Color4f(1.f, 1.f, 0.f) == Color4f::yellow);
	TestAssert(Color4f(0.f, 1.f, 1.f) == Color4f::cyan);
	TestAssert(Color4f(1.f, 0.f, 1.f) == Color4f::magenta);
}
//------------------------------------------------------------------------------
// 値の設定テスト
void Color4fTest::testSetValue(){
	Color4f col0;
	col0.set(1.f, 1.f, 1.f);
	TestAssert(Color4f::white == col0);
	col0.set(1.f, 1.f, 1.f, 1.f - Math::epsilon);
	TestAssert(Color4f::white != col0);
	// 三要素キャラクタカラーの設定
	col0.set(Color3c(64, 128, 192));
	TestAssert(Color4f(64.f / 255.f, 128.f / 255.f, 192.f / 255.f, 1.f).
		epsilonEquals(col0, Math::epsilon));
	// 四要素キャラクタカラーの設定
	col0.set(Color4c(64, 128, 192, 64));
	TestAssert(Color4f(
		64.f / 255.f, 128.f / 255.f, 192.f / 255.f, 64.f / 255.f).
		epsilonEquals(col0, Math::epsilon));
	// 三要素実数カラーの設定
	col0.set(Color3f(1.f, 2.f, 3.f));
	TestAssert(Color4f(1.f, 2.f, 3.f, 1.f) == col0);
}
//------------------------------------------------------------------------------
// 演算
void Color4fTest::testArithmetic(){
	// 加算
	Color4f col0(0.25f, 0.25f, 0.25f, 0.5f), col1(0.25f, 0.5f, 1.f, 2.f), col2;
	col2 = col0 + col1;
	TestAssert(Color4f(0.5f, 0.75f, 1.25f, 2.5f) == col2);
	// 減算
	col2 = col2 - col1;
	TestAssert(col0 == col2);
	// 乗算
	col0.set(0.5f, 0.5f, 0.5f, 0.5f);
	col0 = col0 * col0;
	TestAssert(Color4f(0.25f, 0.25f, 0.25f, 0.25f) == col0);
	col0 = col0 * 2.f;
	TestAssert(Color4f(0.5f, 0.5f, 0.5f, 0.5f) == col0);
	col0 = 0.5f * col0;
	TestAssert(Color4f(0.25f, 0.25f, 0.25f, 0.25f) == col0);
	// +-演算子
	TestAssert(col0 == +col0);
	TestAssert(Color4f(-0.25f, -0.25f, -0.25f, -0.25f) == -col0);
}
//------------------------------------------------------------------------------
// 代入演算
void Color4fTest::testSubstitutionArithmetic(){
	// 加算
	Color4f col0(0.25f, 0.25f, 0.25f, 0.5f), col1(0.25f, 0.5f, 1.f, 2.f), col2;
	col2 = col0;
	col0 += col1;
	TestAssert(Color4f(0.5f, 0.75f, 1.25f, 2.5f) == col0);
	// 減算
	col0 -= col1;
	TestAssert(col2 == col0);
	// 乗算
	col0.set(0.5f, 0.5f, 0.5f, 0.5f);
	col0 *= col0;
	TestAssert(Color4f(0.25f, 0.25f, 0.25f, 0.25f) == col0);
	col0 *= 2.f;
	TestAssert(Color4f(0.5f, 0.5f, 0.5f, 0.5f) == col0);
}
//------------------------------------------------------------------------------
// 色演算
void Color4fTest::testColorArithmetic(){
	// クランプ
	Color4f clamp(-1.f, 2.f, 0.8f, 0.2f);
	clamp.clamp();
	TestAssert(Color4f(0.f, 1.f, 0.8f, 0.2f) == clamp);
	clamp.upperClamp(0.6f);
	TestAssert(Color4f(0.f, 0.6f, 0.6f, 0.2f) == clamp);
	clamp.lowerClamp(0.4f);
	TestAssert(Color4f(0.4f, 0.6f, 0.6f, 0.4f) == clamp);
	// 反対色
	Color4f negColor(0.25f, 0.5f, 0.75f, 1.f);
	negColor.negative();
	TestAssert(Color4f(0.75f, 0.5f, 0.25f, 1.f) == negColor);
	// 線形補間
	Color4f col0(0, 0, 0, 0), col1(1.f, 1.f, 1.f, 1.f);
	for(int i = 0; i < 11; i++){
		float alpha = i * 0.1f;
		Color4f answer(alpha, alpha, alpha, alpha);
		Color4f result = Color4f::lerp(col0, col1, alpha);
		TestAssert(answer == result);
	}
}
//------------------------------------------------------------------------------
// HSVテスト
void Color4fTest::testHSV(){
	Color4f col0;
	col0 = Color4f::white.getHSV();
	TestAssert(col0 == Color4f(0.f, 0.f, 1.f, 1.f));
	col0.setHSV(col0);
	TestAssert(col0 == Color4f::white);

	col0 = Color4f::gray.getHSV();
	TestAssert(col0 == Color4f(0.f, 0.f, 0.5f, 1.f));
	col0.setHSV(col0);
	TestAssert(col0 == Color4f::gray);

	col0 = Color4f::black.getHSV();
	TestAssert(col0 == Color4f(0.f, 0.f, 0.f, 1.f));
	col0.setHSV(col0);
	TestAssert(col0 == Color4f::black);

	col0 = Color4f::red.getHSV();
	TestAssert(col0 == Color4f(0.f, 1.f, 1.f, 1.f));
	col0.setHSV(col0);
	TestAssert(col0 == Color4f::red);

	col0 = Color4f::green.getHSV();
	TestAssert(col0.epsilonEquals(
		Color4f(0.333333f, 1.f, 1.f, 1.f), Math::epsilon));
	col0.setHSV(col0);
	TestAssert(col0.epsilonEquals(Color4f::green, Math::epsilon));

	col0 = Color4f::blue.getHSV();
	TestAssert(col0.epsilonEquals(
		Color4f(0.666666f, 1.f, 1.f, 1.f), Math::epsilon));
	col0.setHSV(col0);
	TestAssert(col0.epsilonEquals(Color4f::blue, Math::epsilon));

	col0 = Color4f::yellow.getHSV();
	TestAssert(col0.epsilonEquals(
		Color4f(0.166666f, 1.f, 1.f, 1.f), Math::epsilon));
	col0.setHSV(col0);
	TestAssert(col0.epsilonEquals(Color4f::yellow, Math::epsilon));

	col0 = Color4f::cyan.getHSV();
	TestAssert(col0.epsilonEquals(
		Color4f(0.5f, 1.f, 1.f, 1.f), Math::epsilon));
	col0.setHSV(col0);
	TestAssert(col0.epsilonEquals(Color4f::cyan, Math::epsilon));

	col0 = Color4f::magenta.getHSV();
	TestAssert(col0 == Color4f(0.8333333f, 1.f, 1.f, 1.f));
	col0.setHSV(col0);
	TestAssert(col0.epsilonEquals(Color4f::magenta, Math::epsilon));
}
//------------------------------------------------------------------------------
// 論理演算テスト
void Color4fTest::testLogicalOperation(){
	Color4f col0(0.5f, 1.f, 2.f), col1(0.5f, 1.f, 2.f);
	TestAssert(col0 == col1);
	TestAssert(!(col0 != col1));
	col1.r += 1.f;
	TestAssert(!(col0 == col1));
	TestAssert(col0 != col1);
	TestAssert(col0.epsilonEquals(col1, 1.f));
	TestAssert(!col0.notEpsilonEquals(col1, 1.f));
	col1.r += Math::epsilon;
	TestAssert(!col0.epsilonEquals(col1, 1.f));
	TestAssert(col0.notEpsilonEquals(col1, 1.f));
}
//------------------------------------------------------------------------------
// 文字列テスト
void Color4fTest::testToString(){
	Color4f col0(0.5f, 1.f, 2.f);
	TestEquals(
		"( 0.50000000, 1.00000000, 2.00000000, 1.00000000 )",
		col0.toString());
}
//------------------------------------------------------------------------------
