//------------------------------------------------------------------------------
// 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 "LampBasic.h"
#include "Sound/Utility/SoundList.h"
#include "Sound/Utility/SoundCache.h"
#include "Core/InputOutput/TextFileReader.h"
#include "Core/InputOutput/FilePath.h"
#include "Core/Utility/StringTokenizer.h"

namespace Lamp{

//------------------------------------------------------------------------------
// ロード
bool SoundList::load(SoundCache* soundCache, const String& filePath){
	FilePath path(filePath);
	if(!path.existFile()){ return false; }
	TextFileReader* reader = new TextFileReader(filePath);
	bool result = load(soundCache, reader);
	delete reader;
	return result;
}
//------------------------------------------------------------------------------
// ロード
bool SoundList::load(SoundCache* soundCache, TextReader* textReader){
	String line;
	while(!textReader->isEnd()){
		String line = textReader->readLine();
		if(!loadSound(soundCache, line)){ return false; }
	}
	return true;
}
//------------------------------------------------------------------------------
// サウンドのロード
bool SoundList::loadSound(SoundCache* soundCache, const String& line){
	String temp, errorMethod("SoundList::loadSound() ");
	StringTokenizer tokenizer(line, "\t");
	// 空行チェック
	if(!tokenizer.hasMoreTokens()){ return true; }
	temp = tokenizer.getNextToken();
	// コメントチェック
	if(temp.startsWith("//")){ return true; }

	// ファイル名
	String fileName;
	fileName = temp;

	// ステレオ、3D
	bool isStereo;
	if(!tokenizer.hasMoreTokens()){
		ErrorOut(errorMethod + "ステレオ、3D指定がありません。" + line);
		return false;
	}
	temp = tokenizer.getNextToken();
	if(temp.equalsIsIgnoreCase("stereo")){
		isStereo = true;
	}else if(temp.equalsIsIgnoreCase("3d")){
		isStereo = false;
	}else{
		ErrorOut(errorMethod + "ステレオ、3D指定には"
			"「Stereo」か「3D」を指定して下さい。" + line);
		return false;
	}

	// ループ
	bool isLoop;
	if(!tokenizer.hasMoreTokens()){
		ErrorOut(errorMethod + "ループ指定がありません。" + line);
		return false;
	}
	temp = tokenizer.getNextToken();
	if(temp.equalsIsIgnoreCase("loop")){
		isLoop = true;
	}else if(temp.equalsIsIgnoreCase("once")){
		isLoop = false;
	}else{
		ErrorOut(errorMethod + "ループ指定には"
			"「Loop」か「Once」を指定して下さい。" + line);
		return false;
	}

	// プライオリティ
	int priority;
	if(!tokenizer.hasMoreTokens()){
		ErrorOut(errorMethod + "プライオリティ指定がありません。" + line);
		return false;
	}
	temp = tokenizer.getNextToken();
	if((!temp.parseInt(&priority)) ||
		(priority > Limit::shortMax) || (priority < Limit::shortMin)){
		ErrorOut(errorMethod + "プライオリティは32767〜-32768の整数で"
			"指定してください。" + line);
		return false;
	}

	// 最大ミキシング数
	int maxMixingCount;
	if(!tokenizer.hasMoreTokens()){
		ErrorOut(errorMethod + "最大ミキシング数指定がありません。" + line);
		return false;
	}
	temp = tokenizer.getNextToken();
	if((!temp.parseInt(&maxMixingCount)) || (maxMixingCount < 0)){
		ErrorOut(errorMethod + "最大ミキシング数は0以上の整数で"
			"指定してください。" + line);
		return false;
	}

	// 最小3D距離、最大3D距離
	float minimum3DDistance;
	float maximum3DDistance;
	if(!isStereo){
		// 最小3D距離
		if(!tokenizer.hasMoreTokens()){
			ErrorOut(errorMethod + "最小3D距離指定がありません。" + line);
			return false;
		}
		temp = tokenizer.getNextToken();
		if((!temp.parseFloat(&minimum3DDistance)) ||
			(minimum3DDistance <= 0.f)){
			ErrorOut(errorMethod + "最小3D距離は正の距離を実数で"
				"指定してください。" + line);
			return false;
		}

		// 最大3D距離
		if(!tokenizer.hasMoreTokens()){
			ErrorOut(errorMethod + "最小3D距離指定がありません。" + line);
			return false;
		}
		temp = tokenizer.getNextToken();
		if((!temp.parseFloat(&maximum3DDistance)) ||
			(maximum3DDistance <= 0.f)){
			ErrorOut(errorMethod + "最大3D距離は正の距離を実数で"
				"指定してください。" + line);
			return false;
		}
		if(maximum3DDistance < minimum3DDistance){
			ErrorOut(errorMethod + "最大3D距離は最小3D距離よりも大きな実数を"
				"指定してください。" + line);
			return false;
		}
	}

	// サウンドのロード
	if(isStereo){
		if(!soundCache->loadStaticSound(
			fileName, isLoop, priority, maxMixingCount)){
			ErrorOut(errorMethod + "静的サウンドの"
				"ロードに失敗しました。" + line);
			return false;
		}
	}else{
		if(!soundCache->loadStaticSound3D(fileName, isLoop, priority,
			minimum3DDistance, maximum3DDistance, maxMixingCount)){
			ErrorOut(errorMethod + "静的3Dサウンドの"
				"ロードに失敗しました。" + line);
			return false;
		}
	}
	return true;
}
//------------------------------------------------------------------------------
} // End of namespace Lamp
//------------------------------------------------------------------------------
