////////////////////////////////////////////////////////////////////////////////
// MechVM.h
// Main window for MechVM
// Developed since 2007
////////////////////////////////////////////////////////////////////////////////

#ifndef MechVM__h
#define MechVM__h

#include "MWBase.h"

#include "GLButton.h"
#include "GLSlider.h"
#include "GLLabel.h"
#include "GLComboBox.h"
#include "GLLineEdit.h"
#include "GLTableView.h"
#include "MechShell.h"

class SmackerView;

///////////////////////////////////////////////////////////////////////////////
// Global constants

#define margin 10
#define InitialWindowWidth 400
#define InitialWindowHeight 300

#define buttonTop margin
#define buttonLeft margin
#define buttonDist 20

const int playGameButtonID = 0;
const int viewFileButtonID = 1;
const int MechLabButtonID = 2;
const int installButtonID = 3;
const int MW2PRJTableContextMenu = 8;

int getDefaultButtonHeight();

////////////////////////////////////////////////////////////////////////////////
// Misc functions

const char* getVersionStr ();

////////////////////////////////////////////////////////////////////////////////

// Interface for classes that process SDL joystick events
class JoystickListener {
public:
	virtual void joystickEvent(SDL_Event* event) = 0;
};

// Register the class passed as a listener for joystick events, if possible
SDL_Joystick* registerJoystickListener(JoystickListener* listener);

// Unregister the class passed as a listener for joystick events
void unregisterJoystickListener(JoystickListener* listener);

////////////////////////////////////////////////////////////////////////////////
// MechVM main window

class MechVM: public GLWindowContainer
{
public:
	// Constructor, destructor
	MechVM();
	~MechVM() OVERRIDE;

	void showGameScreen();

	// Receive messages
	virtual void receiveMessage (VirtualClass* sender, int MessageType, VirtualClass* data = nullptr);

	// Process toolbar button event
	void processToolbarButtonEvent(VirtualClass* sender);

	// Update title with model graph name and framerate
	void updateTitle ();

	// Render
	virtual void renderBase(int x, int y, int w, int h);

	void startMechLab(GLWindow* returnWin);

	void startCampaign();

	// Called to set new layout
	static void createToolbar(GLWindowContainer* container);

	// Get SDL_Window
	SDL_Window* getWindow()
	{ return mSdlWindow; }
	void setWindow(SDL_Window* win)
	{ mSdlWindow = win; }

	void buttonStateChange (int button, bool down, int x, int y);

	void setScreen(GLWindow* newScreen);

	void renderScene();

	// Restore MechVM as main window
	void restore();

	void keyPressed (BGKey key, bool shiftHeld, bool controlHeld, bool down, bool repeat);

	// Window size changed
	void changeSize (GLsizei width, GLsizei height);

	void mouseMovedBroker (int x, int y);

	// Create a button
	static GLButton* addButton(GLWindowContainer* container, int num, const BGCPString& name, int ID);

	// Mark objects for deletion. They will be deleted when little else is on the stack.
	void deleteLater(VirtualClass* object);

	// Delete all objects that were marked for deletion
	void deleteNow();

	// View file
	void viewExternalFile();
	void ViewPRJFile();

	bool isInFullscreenMode() const;
	void setFullscreenMode(bool newVal);

	void mouseWheelMoved(int /*x*/, int /*y*/) OVERRIDE;

private:
	GLButton * playGame, * MechLabButton, * viewFileButton, * installButton, 
		* unpackPrjButton, * setRenderingDistanceButton;
	MWEquipment* weapons;
	size_t weaponsCount;
	GLTableView* gameTable;
	SDL_Window* mSdlWindow;
	bool mFullScreen;
	GLWindow* mScreen;
	std::vector<VirtualClass*> mDeleteLater;
	SmackerView* smkView;

	// Create a pairs of a label and another control
	// type: 0=LineEdit, 1=Slider, 2=ComboBox
	GLWindow* createControls (const char* title, int num, int type);

	void getSelectedMW2PRJFileName (BGCPString& FN);
	MemoryBlock* getSelectedMW2PRJFile ();

	// Show widgets for starting installation or data import
	void showInstallWidgets();
	size_t showCDROMWidgets();
	void showCDROMReportWidgets(int y);
	void createInstallButton(size_t& count, const PathChar* CDpath);
};

MechVM* getMechVm();

#endif
