/* 
 *	Copyright (C) 2003-2006 Gabest
 *	http://www.gabest.org
 *
 *  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, 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 GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#pragma once

#include "File.h"

namespace ssf
{
	struct Point {float x, y;};
	struct PointAuto : public Point {bool auto_x, auto_y;};
	struct Size {float cx, cy;};
	struct Rect {float t, r, b, l;};
	struct Align {float v, h;};
	struct Angle {float x, y, z;};
	struct Color {float a, r, g, b; operator DWORD(); void operator = (DWORD c);};
	struct Frame {CStringW reference; Size resolution;};
	struct Direction {CStringW primary, secondary;};
	struct Time {float start, stop;};
	struct Background {Color color; float size, blur; CStringW type;};
	struct Shadow {Color color; float depth, angle, blur;};

	class Path : public CAtlArray<Point>
	{
	public: 
		Path() {} 
		Path(const Path& path) {*this = path;} 
		Path& operator = (const Path& path) {Copy(path); return *this;} 
		Path(LPCWSTR str) {*this = str;} 
		Path& operator = (LPCWSTR str);
		CStringW ToString();
	};

	struct Placement 
	{
		Rect clip, margin; 
		Align align; 
		PointAuto pos; 
		Point offset;
		Angle angle; 
		PointAuto org;
		Path path;
	};

	struct Font
	{
		CStringW face;
		float size, weight;
		Color color;
		bool underline, strikethrough, italic;
		float spacing;
		Size scale;
		bool kerning;
	};

	struct Fill
	{
		static unsigned int gen_id;
		int id;
		Color color;
		float width;
		struct Fill() : id(0) {}
	};

	struct Style
	{
		CStringW linebreak;
		Placement placement;
		Font font;
		Background background;
		Shadow shadow;
		Fill fill;

		bool IsSimilar(const Style& s);
	};

	struct Text
	{
		enum {SP = 0x20, NBSP = 0xa0, LSEP = 0x0a};
		Style style;
		CStringW str;
	};

	class Subtitle
	{
		static struct n2n_t {StringMapW<float> align[2], weight, transition;} m_n2n;

		File* m_pFile;

		void GetStyle(Definition* pDef, Style& style);
		float GetMixWeight(Definition* pDef, float at, StringMapW<float>& offset, int default_id);
		template<class T> bool MixValue(Definition& def, T& value, float t);
		template<> bool MixValue(Definition& def, float& value, float t);
		template<class T> bool MixValue(Definition& def, T& value, float t, StringMapW<T>* n2n);
		template<> bool MixValue(Definition& def, float& value, float t, StringMapW<float>* n2n);
		template<> bool MixValue(Definition& def, Path& value, float t);
		void MixStyle(Definition* pDef, Style& dst, float t);

		void Parse(InputStream& s, Style style, float at, StringMapW<float> offset, Reference* pParentRef);

		void AddChar(Text& t, WCHAR c);
		void AddText(Text& t);

	public:
		CStringW m_name;
		bool m_animated;
		Frame m_frame;
		Direction m_direction;
		CStringW m_wrap;
		float m_layer;
		Time m_time;
		CAtlList<Text> m_text;

	public:
		Subtitle(File* pFile);
		virtual ~Subtitle();

		bool Parse(Definition* pDef, float start, float stop, float at);
	};
};