/////////////////////////////////////////////////////////////////////////////
// Name:        Menu.h
// Purpose:     The class to store a DVD Menu
// Author:      Alex Thuering
// Created:	    04.11.2003
// RCS-ID:      $Id: Menu.h,v 1.47 2010/01/24 18:56:06 ntalex Exp $
// Copyright:   (c) Alex Thuering
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////

#ifndef MENU_H
#define MENU_H

#include "MenuObject.h"
#include "mediaenc.h"

enum MenuDrawType {
	mdALL,
	mdBACKGROUND,
	mdBUTTONS_NORMAL,
	mdBUTTONS_HIGHLIGHTED,
	mdBUTTONS_SELECTED
};

WX_DEFINE_ARRAY(DVDAction*, DVDActions);
WX_DEFINE_ARRAY(MenuObject*, MenuObjects);
class DVD;

class Menu {
public:
	/**
	 * Constructor
	 * @param dvd The reference to DVD
	 * @param tsi The index of titleset
	 * @param videoFormat The video format (PAL/NTSC)
	 * @param aspectRatio The aspectRatio (4:3/16:9)
	 */
	Menu(DVD* dvd, int tsi, VideoFormat videoFormat = vfPAL, AspectRatio aspectRatio = ar4_3);
	~Menu();
	
	inline wxSVGDocument* GetSVG() { return m_svg; }
	
	inline VideoFormat GetVideoFormat() { return m_videoFormat; }
	void SetVideoFormat(VideoFormat format);
	wxSize GetResolution();
	inline AspectRatio GetAspectRatio() { return m_aspectRatio; }
	inline void SetAspectRatio(AspectRatio aspectRatio) { m_aspectRatio = aspectRatio; }
	
	inline wxString GetStartTime() { return m_startTime; }
	inline void 	SetStartTime(wxString time) { m_startTime = time; }
	inline wxString GetEndTime() { return m_endTime; }
	inline void 	SetEndTime(wxString time) { m_endTime = time; }
	
	void SetBackground(wxString fileName);
	wxString GetBackground();
	void SetBackgroundColour(wxColour colour);
	wxColour GetBackgroundColour();
	bool HasVideoBackground();
	
	wxString AddImage(wxString fileName, int x = -1, int y = -1);
	wxString AddText(wxString text, int x = -1, int y = -1);
	wxString AddObject(wxString fileName, wxString param, int x = -1, int y = -1);
	
	/** Returns the count of menu objects inclusive buttons */
	unsigned int GetObjectsCount() { return m_objects.Count(); }
	/** Returns the count of buttons */
	unsigned int GetButtonsCount();
	/** Returns menu object with given index */
	MenuObject* GetObject(int index) { return m_objects[index]; }
	/** Returns menu object with given id */
	MenuObject* GetObject(wxString id);
	/** Removes menu object with given id */
	void RemoveObject(wxString id);
	inline void ObjectToFront(wxString id) { MenuObject* obj = GetObject(id); if (obj) obj->ToFront(); }
	inline void ObjectForward(wxString id) { MenuObject* obj = GetObject(id); if (obj) obj->Forward(); }
	inline void ObjectBackward(wxString id) { MenuObject* obj = GetObject(id); if (obj) obj->Backward(); }
	inline void ObjectToBack(wxString id) { MenuObject* obj = GetObject(id); if (obj) obj->ToBack(); }
	inline bool IsFirstObject(wxString id) { MenuObject* obj = GetObject(id); return obj && obj->IsFirst(); }
	inline bool IsLastObject(wxString id) { MenuObject* obj = GetObject(id); return obj && obj->IsLast(); }
	/** Returns true if button with given id is the first button */
	bool IsFirstButton(wxString id);
	/** Makes button with given id the first button */
	void SetFirstButton(wxString id);
	
	inline unsigned int GetActionsCount() { return m_actions.Count(); }
	inline DVDAction* GetAction(int index) { return m_actions[index]; }
	
	void SetTransparentColor();
	wxImage GetImage(int width, int height);
	
	bool ReduceColours();
	wxImage* GetImages();
	wxSVGDocument* GetBackgroundSVG();
	
	bool SaveSpumux(wxString fileName, wxString btFile, wxString hlFile, wxString selFile);
	wxSvgXmlNode* GetXML(DVDFileType type, wxSvgXmlNode* node = NULL);
	bool PutXML(wxSvgXmlNode* node);
	/** Stores object data to string */
	wxString Serialize();
	/** Restores object from data */
	void Deserialize(const wxString& data);
	
	wxString AddObject(wxSvgXmlNode* node, bool fixPosition = false);
	
	/** Updates image in buttons with action jump to given title */
	void UpdateButtonImageFor(int actionTsi, int actionPgci, wxString uri);
	/** Fix coordinates of buttons if they are out of range */
	void FixButtonCoordinates();
	
	/** Creates and initializes SVG Document */
	static wxSVGDocument* CreateSVG(int width, int height);
private:
	DVD* m_dvd;
	int m_tsi;
	wxSVGDocument* m_svg;
	VideoFormat m_videoFormat;
	AspectRatio m_aspectRatio;
	wxString 	m_startTime, m_endTime;
	wxColour 	m_transpColour;
	MenuObjects m_objects;
	DVDActions m_actions;
	void SetBackground(wxSVGSVGElement* svg, wxString fileName);
	wxString GetBackground(wxSVGSVGElement* svg);
	void FixPosition(MenuObject* obj); /** for copy & paste */
	bool IsDefElement(wxSVGElement* element);
	void RemoveChangeable(wxSVGElement* element, MenuObject* obj);
	bool RemoveNotChangeable(wxSVGElement* element, MenuObject* obj);
	wxSVGSVGElement* GetSVGCopy(MenuDrawType drawType = mdALL);
	wxImage RenderImage(MenuDrawType drawType, int width, int height);
	wxImage GetImage(MenuDrawType drawType, int width = -1, int height = -1);
};

#endif // MENU_H
