#include <vector>
#include <string>

#if defined(__APPLE__)
#include <OpenGL/gl.h>
#else
#include <windows.h>
#include <gl/gl.h>
#endif

#include "psychlops_g_cache.h"

namespace Psychlops {
namespace Utilities {


	////////	TextCacheAllocation	////////
	CacheOnImage::CacheOnImage() {  }
	CacheOnImage::~CacheOnImage() { uncache(); }
	void CacheOnImage::dirty() { dirty_ = true; }
	void CacheOnImage::uncache()
	{
		img.release();
	}
	void CacheOnImage::draw(
		Letters &drawee, const double xx, const double yy,
		const double r, const double g, const double b, const double a,
		const int horiz_align, const int vertical_align, const double max_width, Drawable &outer)
	{
		const int anchor = horiz_align, vertical_anchor = vertical_align;
		double mx = xx, my = yy;
		//double mx = drawee.getDatum().x, my = drawee.getDatum().y;

		double x, y;
		switch(anchor) {
			case Letters::TEXT_ALIGN_CENTER:
				x = mx - img.getWidth() / 2;
				break;
			case Letters::TEXT_ALIGN_RIGHT:
				x = mx - img.getWidth();
				break;
			case Letters::NOT_SPECIFIED:
			case Letters::TEXT_ALIGN_LEFT:
			default:
				x = mx;
				break;
		}
		switch(vertical_anchor) {
			case Letters::TEXT_ALIGN_MIDDLE:
				y = my;
				img.centering(x, y);
				break;
			case Letters::TEXT_ALIGN_TOP:
				y = my;
				img.move_to(x, y);
				break;
			default:
				y = my - drawee.font.size;
				img.move_to(x, y);
				break;
		}
		//img.draw(outer);

		Color col(r,g,b,a);
		Rectangle targetarea(img.getLeft(), img.getTop(), img.getRight(), img.getBottom());
		const Color zero_alpha(1,1,1,0,false);
		glPushAttrib(GL_COLOR_BUFFER_BIT);
		//img.move_to(posX, posY-cache_baseY);

		// clear destination alpha
		glBlendFunc(GL_ZERO, GL_SRC_COLOR);
		targetarea.draw(zero_alpha, outer);

		// draw font in alpha channel
		glBlendFunc(GL_ONE, GL_ONE);
		img.draw(outer);

		// apply alpha factor
		if(a!=1) {
			Color alpha_mask(1,1,1,a,false);
			glBlendFunc(GL_ZERO, GL_SRC_COLOR);
			targetarea.draw(alpha_mask, outer);
		}

		// drawing in specified color by destination alpha
		glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
		targetarea.draw(col, outer);

		//		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glPopAttrib();
	}


	////////	TextCacheManager	////////
	bool TextCacheManager::isCached(Letters *letters)
	{
		return (map.count(letters) != 0);// && !(image_cache[img].dirty_);
	}
	void TextCacheManager::cache(Letters *letters, CacheOnImage *allocation)
	{
		map[letters] = allocation;
	}
	void TextCacheManager::uncache(Letters *letters)
	{
		if( isCached(letters) ) {
			map[letters]->uncache();
			map.erase(letters);
		}
	}
	void TextCacheManager::uncacheAll()
	{
		map.clear();
	}


}
}	/*	<- namespace Psycholops 	*/

