/*********************************************************\
         __      __           __  __
        / /     / / _____    / / / / ______   __     __
       / /     / / /___  \  / / / / / ___  | / /    / /
      / /_____/ / _____| / / / / / / /__/ / / /    / /
     / ______  / / ___  / / / / / / _____/ / /    / /
    / /     / / / /__/ / / / / / / |____  / |____/ /
   /_/     /_/ |______/ /_/ /_/  \_____/  \_____  /
                                         ______/ /
            High Level Game Framework   /_______/

  ------------------------------------------------------

  Copyright (c) 2009 - Rodrigo Braz Monteiro.
  This file is subject to the terms of license.txt.

\*********************************************************/

#pragma once

#include "halleystring.h"
#include "rect.h"
#include <boost/array.hpp>

namespace Halley {
	class Texture {
	public:
		enum AlphaType {
			ALPHA_OPAQUE,
			ALPHA_TEST,
			ALPHA_BLEND,
			ALPHA_ADD
		};

		Texture(String _name) : name(_name) {}
		virtual ~Texture() {}

		String GetName() const { return name; }

		virtual int GetId() const = 0;
		virtual void Bind() = 0;

		virtual Rect4i GetArea() const { return Rect4i(0,0,w,h); }
		virtual void GetTexCoords(float* buffer) const;
		virtual AlphaType GetAlphaType() { return ALPHA_OPAQUE; }

		Uint16 GetW() { return w; }
		Uint16 GetH() { return h; }
		void SetW(Uint16 _w) { w = _w; }
		void SetH(Uint16 _h) { h = _h; }


	private:
		String name;
		Uint16 w;
		Uint16 h;
	};

	class ConcreteTexture : public Texture {
	public:
		ConcreteTexture(String filename);
		~ConcreteTexture();

		void Bind();
		AlphaType GetAlphaType() { return alphaType; }
		int GetId() const { return (int) id; }

	private:
		unsigned int id;
		float tw;
		float th;
		AlphaType alphaType;

		void GetTexCoords(float* buffer) const;
		AlphaType GetSurfaceAlphaType(const SDL_Surface *surface);
		void LoadTexture(String filename);
		void DestroyTexture();
	};

	class SubTexture : public Texture {
	public:
		SubTexture(spTexture _parent, Rect4i _area);
		
		void Bind();
		Rect4i GetArea() const { return area; }
		void GetTexCoords(float* buffer) const;
		AlphaType GetAlphaType();

	private:
		spTexture parent;
		Rect4i area;
		boost::array<float, 8> texCoords;
	};
}
