/* 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.
 *
 */

#ifndef TSAGE_RINGWORLD2_SCENES2_H
#define TSAGE_RINGWORLD2_SCENES2_H

#include "common/scummsys.h"
#include "tsage/converse.h"
#include "tsage/events.h"
#include "tsage/core.h"
#include "tsage/scenes.h"
#include "tsage/globals.h"
#include "tsage/sound.h"
#include "tsage/ringworld2/ringworld2_logic.h"
#include "tsage/ringworld2/ringworld2_speakers.h"

namespace TsAGE {

namespace Ringworld2 {

using namespace TsAGE;

class Scene2000 : public SceneExt {
	class Action1 : public ActionExt {
	public:
		virtual void signal();
	};

	class WestExit : public SceneExit {
	public:
		virtual void changeScene();
	};
	class EastExit : public SceneExit {
	public:
		virtual void changeScene();
	};
	class SouthExit : public SceneExit {
	public:
		virtual void changeScene();
	};
	class NorthExit : public SceneExit {
	public:
		virtual void changeScene();
	};
	class DoorExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	bool _exitingFlag;
	int _mazePlayerMode;

	NamedHotspot _background;
	SceneActor _companion;
	SceneActor _persons[11];
	WestExit _westExit;
	EastExit _eastExit;
	SouthExit _southExit;
	NorthExit _northExit;
	DoorExit _doorExit;
	Action1 _action1, _action2, _action3, _action4, _action5;
	SequenceManager _sequenceManager;

	Scene2000();
	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
	virtual void process(Event &event);
	virtual void synchronize(Serializer &s);

	void initExits();
	void initPlayer();
};

class Scene2350 : public SceneExt {
	class Companion : public SceneActor {
		virtual bool startAction(CursorType action, Event &event);
	};
	class Balloon : public SceneActor {
		virtual bool startAction(CursorType action, Event &event);
	};

	class ExitUp : public SceneExit {
		virtual void changeScene();
	};
	class ExitWest : public SceneExit {
		virtual void changeScene();
	};
public:
	SpeakerQuinn _quinnSpeaker;
	SpeakerPharisha _pharishaSpeaker;
	NamedHotspot _background;
	SceneActor _person;
	Companion _companion;
	Balloon _balloon;
	Balloon _harness;
	ExitUp _exitUp;
	ExitWest _exitWest;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
};

class Scene2400 : public SceneExt {
	class WestExit : public SceneExit {
		virtual void changeScene();
	};
	class EastExit : public SceneExit {
		virtual void changeScene();
	};
public:
	WestExit _westExit;
	EastExit _eastExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
};

class Scene2425 : public SceneExt {
	class RopeDest1 : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};
	class RopeDest2 : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};
	class Crevasse : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};
	class Background : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};

	class Rope : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class Pictographs : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class SouthEastExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	RopeDest1 _ropeDest1;
	RopeDest2 _ropeDest2;
	Crevasse _crevasse;
	Background _background;
	Rope _rope;
	Pictographs _pictographs1;
	Pictographs _pictographs2;
	SouthEastExit _southEastExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
};

class Scene2430 : public SceneExt {
	class Companion : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class GunPowder : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class OilLamp : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class SouthExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	NamedHotspot _background;
	NamedHotspot _bottles2;
	NamedHotspot _furnishings;
	NamedHotspot _rug1;
	NamedHotspot _mirror;
	NamedHotspot _garments;
	NamedHotspot _bed;
	NamedHotspot _towel;
	NamedHotspot _bottles1;
	NamedHotspot _post;
	NamedHotspot _clothesPile1;
	NamedHotspot _clothesPile2;
	NamedHotspot _rug2;
	Companion _companion;
	GunPowder _gunPowder;
	OilLamp _oilLamp;
	SouthExit _southExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
};

class Scene2435 : public SceneExt {
	class Companion : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class Astor : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class SouthExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	SpeakerQuinn2435 _quinnSpeaker;
	SpeakerSeeker2435 _seekerSpeaker;
	SpeakerPharisha2435 _pharishaSpeaker;
	NamedHotspot _background;
	NamedHotspot _leftWindow;
	NamedHotspot _rightWindow;
	Companion _companion;
	Astor _astor;
	SouthExit _southExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
};

class Scene2440 : public SceneExt {
	class Companion : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class OilLamp : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class SouthEastExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	NamedHotspot _background;
	NamedHotspot _garments;
	NamedHotspot _bedspread;
	NamedHotspot _post;
	NamedHotspot _rug;
	NamedHotspot _furnishings;
	NamedHotspot _bottles;
	Companion _companion;
	OilLamp _oilLamp;
	SouthEastExit _southEastExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
};

class Scene2445 : public SceneExt {
public:
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
};

class Scene2450 : public SceneExt {
	class Parker : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class CareTaker : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class SouthWestExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	SpeakerQuinn2450 _quinnSpeaker;
	SpeakerSeeker2450 _seekerSpeaker;
	SpeakerCaretaker2450 _caretakerSpeaker;
	NamedHotspot _background;
	NamedHotspot _post;
	NamedHotspot _bedspread;
	SceneActor _companion;
	Parker _parker;
	CareTaker _careTaker;
	SouthWestExit _southWestExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
};

class Scene2455 : public SceneExt {
	class Lamp : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class Pool : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class ScrithKey : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class NorthExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	NamedHotspot _background;
	Lamp _lamp;
	Pool _pool;
	ScrithKey _scrithKey;
	NorthExit _northExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
};

class Scene2500 : public SceneExt {
	class WestExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	SpeakerQuinn _quinnSpeaker;
	SpeakerSeeker _seekerSpeaker;
	SpeakerMiranda _mirandaSpeaker;
	SpeakerWebbster2500 _webbsterSpeaker;
	NamedHotspot _background;
	SceneActor _companion;
	SceneActor _quinn;
	SceneActor _ship;
	WestExit _westExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
};

class Scene2525 : public SceneExt {
	class StopCock : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};

	class GlassDome : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class SouthExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	NamedHotspot _background;
	NamedHotspot _machine;
	NamedHotspot _pipes1;
	NamedHotspot _pipes2;
	StopCock _stopcock;
	SceneActor _companion;
	SceneActor _compressor;
	GlassDome _glassDome;
	SouthExit _southExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
};

class Scene2530 : public SceneExt {
	class Flask : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class Crank : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class SouthExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	NamedHotspot _background;
	NamedHotspot _crank2;
	NamedHotspot _shelf;
	NamedHotspot _item4;
	NamedHotspot _rope;
	SceneActor _companion;
	Flask _flask;
	Crank _crank;
	SouthExit _southExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
};

class Scene2535 : public SceneExt {
	class RebreatherTank : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};
	class TannerMask : public SceneActor {
	public:
		bool startAction(CursorType action, Event &event);
	};

	class SouthExit : public SceneExit {
	public:
		virtual void changeScene();
	};
public:
	NamedHotspot _background;
	NamedHotspot _roof;
	NamedHotspot _skin1;
	NamedHotspot _skin2;
	NamedHotspot _skin3;
	NamedHotspot _skin4;
	NamedHotspot _depression;
	SceneActor _companion;
	SceneActor _rope;
	RebreatherTank _rebreatherTank;
	TannerMask _tannerMask;
	SouthExit _southExit;
	SequenceManager _sequenceManager;

	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
};

class Scene2600 : public SceneExt {
public:
	SequenceManager _sequenceManager;
	PaletteRotation *_rotation;

	Scene2600();
	virtual void synchronize(Serializer &s);
	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
};

class Scene2700 : public SceneExt {
	class Action1: public Action {
	public:
		void signal();
	};
	class Action2: public Action {
	public:
		void signal();
	};
	class Action3: public Action {
	public:
		void signal();
	};
	class Action4: public Action {
	public:
		void signal();
	};

	class SouthExit: public SceneArea {
	public:
		void process(Event &event);
	};
	class EastExit: public SceneArea {
	public:
		void process(Event &event);
	};
public:
	SpeakerQuinn2700 _quinnSpeaker;
	SpeakerNej2700 _nejSpeaker;
	NamedHotspot _background;
	NamedHotspot _ghoulHome1;
	NamedHotspot _ghoulHome2;
	NamedHotspot _ghoulHome3;
	NamedHotspot _ghoulHome4;
	NamedHotspot _ghoulHome5;
	SceneActor _nej;
	SceneActor _ghoulHome6;
	SceneActor _ghoulHome7;
	SceneActor _ghoulHome8;
	SceneActor _ghoulHome9;
	Action1 _action1;
	Action2 _action2;
	Action3 _action3;
	Action4 _action4;
	SouthExit _southExit;
	EastExit _eastExit;
	Rect _walkRect1, _walkRect2, _walkRect3;
	Rect _walkRect4, _walkRect5, _walkRect6;
	SequenceManager _sequenceManager;
	int _areaMode, _moveMode, _stripNumber;

	Scene2700();
	virtual void synchronize(Serializer &s);
	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
	virtual void process(Event &event);
};

class Scene2750 : public SceneExt {
	class Action1: public Action {
	public:
		void signal();
	};
	class Action2: public Action {
	public:
		void signal();
	};
	class Action3: public Action {
	public:
		void signal();
	};
	class Action4: public Action {
	public:
		void signal();
	};
	class Action5: public Action {
	public:
		void signal();
	};
	class Action6: public Action {
	public:
		void signal();
	};
	class Action7: public Action {
	public:
		void signal();
	};

	class WestExit: public SceneArea {
	public:
		void process(Event &event);
	};
	class EastExit: public SceneArea {
	public:
		void process(Event &event);
	};
public:
	SpeakerQuinn2750 _quinnSpeaker;
	SpeakerNej2750 _nejSpeaker;
	NamedHotspot _background;
	NamedHotspot _ghoulHome1;
	NamedHotspot _ghoulHome2;
	NamedHotspot _ghoulHome3;
	NamedHotspot _ghoulHome4;
	SceneActor _nej;
	SceneActor _fire;
	SceneActor _bird1;
	SceneActor _folliage1;
	SceneActor _bird2;
	SceneActor _folliage2;
	SceneActor _folliage3;
	SceneActor _folliage4;
	SceneActor _folliage5;
	SceneActor _folliage6;
	SceneActor _folliage7;
	Action1 _action1;
	Action2 _action2;
	Action3 _action3;
	Action4 _action4;
	Action5 _action5;
	Action6 _action6;
	Action7 _action7;
	WestExit _westExit;
	EastExit _eastExit;
	Rect _walkRect1, _walkRect2, _walkRect3;
	SequenceManager _sequenceManager;
	int _areaMode, _moveMode, _stripNumber;

	Scene2750();
	virtual void synchronize(Serializer &s);
	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
	virtual void process(Event &event);
};

class Scene2800 : public SceneExt {
	class Outpost : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};

	class Guard : public SceneActor {
		virtual bool startAction(CursorType action, Event &event);
	};

	class Action1: public Action {
	public:
		void signal();
	};
	class Action2: public Action {
		SceneObject _object2;
		SceneObject _object3;
		SceneObject _object4;
	public:
		void signal();
	};
public:
	SpeakerQuinn2800 _quinnSpeaker;
	SpeakerNej2800 _nejSpeaker;
	SpeakerGuard2800 _guardSpeaker;
	NamedHotspot _background;
	Outpost _outpost;
	Guard _guard;
	SceneActor _nej;
	SceneActor _lightBar;
	SceneObject _bird;
	Action1 _action1;
	Action2 _action2;
	SequenceManager _sequenceManager;
	int _stripNumber;

	Scene2800();
	virtual void synchronize(Serializer &s);
	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void signal();
};

class Scene2900 : public SceneExt {
	/* Items */
	class Scenery : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};
	class ControlPanel : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};
	class Altimeter : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};
	class KnobLeft : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};
	class KnobRight : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};
	class Skip : public NamedHotspot {
	public:
		virtual bool startAction(CursorType action, Event &event);
	};

	/* Actions */
	class Action1: public Action {
	public:
		void signal();
	};

	/* Miscellaneous */
	class Map {
	private:
		void moveArea(Rect &r, int xAmt, int yAmt);
		void moveLine(int xpSrc, int ypSrc, int xpDest, int ypDest, int width);
		int adjustRect(Common::Rect &r1, const Common::Rect &r2);
		void drawBlock(const byte *data, int xp, int yp, const Rect &r1, const Rect &r2);
	public:
		int _mapWidth, _mapHeight;
		int _resNum;
		int _xV, _yV;
		Rect _bounds;

		Map();
		void load(int resNum);
		Common::Point setPosition(const Common::Point &pos, bool initialFlag = false);
		void synchronize(Serializer &s);
		void redraw(Rect *updateRect = NULL);
	};
public:
	SceneObject _leftEdge;
	SceneObject _rightEdge;
	SceneObject _knob;
	SceneObject _altimeterContent;
	SceneObject _knobRightContent;
	SceneObject _knobLeftContent;
	Scenery _scenery;
	ControlPanel _controlPanel;
	Altimeter _altimeter;
	KnobLeft _knobLeft;
	KnobRight _knobRight;
	Skip _skip;
	Action1 _action1;
	Map _map;
	SceneText _skipText;

	bool _controlsActiveChanging;
	bool _altitudeChanging;
	bool _majorMinorFlag;
	int _altitudeMinorChange;
	int _altitudeMajorChange;
	Common::Point _balloonLocation;
	Common::Point _balloonScreenPos;
	int _newAltitude;
	int _xAmount;
	int _xComparison;
	int _fadeCounter;
	bool _paletteReloadNeeded;

	Scene2900();
	virtual void synchronize(Serializer &s);
	virtual void postInit(SceneObjectList *OwnerList = NULL);
	virtual void remove();
	virtual void signal();
	virtual void dispatch();
	virtual void refreshBackground(int xAmount, int yAmount);
};

} // End of namespace Ringworld2
} // End of namespace TsAGE

#endif