/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * 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 "common/system.h"
#include "common/events.h"
#include "graphics/cursorman.h"
#include "graphics/palette.h"
#include "graphics/surface.h"

#include "chewy/cursor.h"
#include "chewy/graphics.h"
#include "chewy/scene.h"
#include "chewy/resource.h"
#include "chewy/text.h"
#include "chewy/video/cfo_decoder.h"

namespace Chewy {

#define MAX_DETAILS 32
#define MAX_HOTSPOTS 50

// Animated details - scene animations
struct AnimatedDetails {
	uint16 x;
	uint16 y;
	// 66 bytes animated details - TODO
};

// Static details - scene sprites and props
struct StaticDetails {
	int16 x;
	int16 y;
	int16 spriteNum;
	uint16 z;
	byte hide;
	// 1 byte dummy
};

struct SceneInfo {
	uint16 staticDetailsCount;
	uint16 animatedDetailsCount;
	uint32 spritePtr;
	AnimatedDetails animatedDetails[MAX_DETAILS];
	StaticDetails staticDetails[MAX_DETAILS];
	Common::Rect hotspot[MAX_HOTSPOTS];
	uint16 hotspotDescRes[MAX_HOTSPOTS];
	Common::String hotspotDesc[MAX_HOTSPOTS];
	byte roomNum;
	byte picNum;
	byte autoMoveCount;
	byte loadTaf;
	Common::String tafName;	// 14 bytes
	byte zoomFactor;
	// 1 byte dummy
	// 6 * 20 = 120 bytes automove coordinates - TODO
	// MAX_DETAILS * 3 * 2 = 192 bytes voc - TODO
	// MAX_DETAILS * 3 = 96 bytes samples - TODO
};

Scene::Scene(ChewyEngine *vm) : _vm(vm) {
	_sceneInfo = new SceneInfo();
}

Scene::~Scene() {
	delete _sceneInfo;
}

void Scene::change(uint scene) {
	_curScene = scene;
	_vm->_cursor->setCursor(0);
	_vm->_cursor->showCursor();
	
	loadSceneInfo();
	draw();
}

void Scene::draw() {
	// Background
	_vm->_graphics->drawImage("episode1.tgp", _curScene);

	// Static details
	for (uint16 i = 0; i < MAX_HOTSPOTS; i++) {
		StaticDetails s = _sceneInfo->staticDetails[i];
		if (s.spriteNum >= 0 && s.x >= 0 && s.y >= 0 && !s.hide)
			_vm->_graphics->drawSprite(Common::String::format("det%d.taf", _curScene), s.spriteNum, s.x, s.y);
	}

	// TODO: These are all hardcoded for now
	_vm->_graphics->drawSprite("det1.taf", 0, 200, 100);
	_vm->_graphics->loadFont("6x8.tff");
	_vm->_graphics->drawText("This is a test", 200, 80);
}

void Scene::updateMouse(Common::Point coords) {
	// Animated details
	// TODO: handle these

	// Static details
	for (uint16 i = 0; i < MAX_HOTSPOTS; i++) {
		if (_sceneInfo->hotspot[i].contains(coords)) {
			// TODO: Draw hotspot description on screen
			debug("Coords %d, %d: '%s'", coords.x, coords.y, _sceneInfo->hotspotDesc[i].c_str());
			break;
		}
	}
}

void Scene::loadSceneInfo() {
	const uint32 sceneInfoSize = 3784;
	const uint32 headerRDI = MKTAG('R', 'D', 'I', '\0');
	const char *sceneIndexFileName = "test.rdi";
	Common::File indexFile;
	if (!Common::File::exists(sceneIndexFileName))
		error("File %s not found", sceneIndexFileName);
	Text *text = new Text();

	indexFile.open(sceneIndexFileName);

	uint32 header = indexFile.readUint32BE();
	if (header != headerRDI)
		error("Invalid resource - %s", sceneIndexFileName);

	indexFile.seek(sceneInfoSize * _curScene, SEEK_CUR);

	// TODO: These can be set to larger numbers than MAX_DETAILS
	_sceneInfo->staticDetailsCount = indexFile.readUint16LE();
	_sceneInfo->animatedDetailsCount = indexFile.readUint16LE();
	indexFile.skip(6);

	// Animated details
	for (int i = 0; i < MAX_DETAILS; i++) {
		_sceneInfo->animatedDetails[i].x = indexFile.readUint16LE();
		_sceneInfo->animatedDetails[i].y = indexFile.readUint16LE();
		indexFile.skip(66);	// animated details info - TODO: read these
	}

	// Static details
	for (int i = 0; i < MAX_DETAILS; i++) {
		_sceneInfo->staticDetails[i].x = indexFile.readSint16LE();
		_sceneInfo->staticDetails[i].y = indexFile.readSint16LE();
		_sceneInfo->staticDetails[i].spriteNum = indexFile.readSint16LE();
		_sceneInfo->staticDetails[i].z = indexFile.readUint16LE();
		_sceneInfo->staticDetails[i].hide = indexFile.readByte();
		indexFile.readByte();	// padding
	}

	// Hotspots
	for (int i = 0; i < MAX_HOTSPOTS; i++) {
		_sceneInfo->hotspot[i].left = indexFile.readUint16LE();
		_sceneInfo->hotspot[i].top = indexFile.readUint16LE();
		_sceneInfo->hotspot[i].right = indexFile.readUint16LE();
		_sceneInfo->hotspot[i].bottom = indexFile.readUint16LE();
		if (!_sceneInfo->hotspot[i].isValidRect())
			warning("Hotspot %d has an invalid rect", i);
	}

	// Hotspot descriptions
	for (int i = 0; i < MAX_HOTSPOTS; i++) {
		_sceneInfo->hotspotDescRes[i] = indexFile.readUint16LE();
		
		if (_sceneInfo->hotspotDescRes[i] < 12) {
			// TODO: Hotspot description IDs are off... investigate why
			_sceneInfo->hotspotDesc[i] = text->getText(_curScene + kADSTextMax, _sceneInfo->hotspotDescRes[i])->text;
		} else {
			// TODO: Handle these types of hotspot descriptions
			warning("Hotspot %d has an invalid description resource (%d)", i, _sceneInfo->hotspotDescRes[i]);
			_sceneInfo->hotspotDesc[i] = Common::String::format("Hotspot %d", _sceneInfo->hotspotDescRes[i]);
		}
	}

	_sceneInfo->roomNum = indexFile.readByte();
	_sceneInfo->picNum = indexFile.readByte();
	_sceneInfo->autoMoveCount = indexFile.readByte();
	_sceneInfo->loadTaf = indexFile.readByte();
	
	for (int i = 0; i < 14; i++)
		_sceneInfo->tafName += indexFile.readByte();

	_sceneInfo->zoomFactor = indexFile.readByte();
	indexFile.readByte();	// padding
	
	// 6 * 20 = 120 bytes automove coordinates - TODO: read these
	// MAX_DETAILS * 3 * 2 = 192 bytes voc - TODO: read these
	// MAX_DETAILS * 3 = 96 bytes samples - TODO: read these

	delete text;
	indexFile.close();
}

} // End of namespace Chewy