#include "standalone2drender.h"
#include "render2d.h"
#include "stacks2d.h"
#include "visualsurface2d.h"
#include "ft_font.h"

void SR_ResetFrameRate(LPSCENERENDER);
void *M4_LoadRenderer();
void *NewVideoOutput();
void *NewVisualRenderer();
M4Err R2D_GetSurfaceAccess(VisualSurface2D *surf);
void R2D_ReleaseSurfaceAccess(VisualSurface2D *surf);
Bool R2D_SupportsFormat(VisualSurface2D *surf, u32 pixel_format);
void R2D_DrawBitmap(VisualSurface2D *surf, struct _texture_handler *txh, M4IRect *clip, M4Rect *unclip);
FontRaster *FT_LoadPlugin();
void FT_Delete(FontRaster *);

static M4Err SA2DR_InitFontEngine(FontRaster *dr)
{
	FTBuilder *ftpriv = (FTBuilder *)dr->priv;

	/*inits freetype*/
	if (FT_Init_FreeType(&ftpriv->library) ) return M4IOErr;

	/*remove the final delimiter*/
    ftpriv->font_dir = "C:\\WINDOWS\\Fonts";
	strcpy(ftpriv->font_serif,"Arial");
	strcpy(ftpriv->font_sans,"Times New Roman");
	strcpy(ftpriv->font_fixed,"Courier New");
	return M4OK;
}

static void SA2DR_SetFontEngine(SceneRenderer *sr)
{
	FontRaster *ifce = FT_LoadPlugin();

	/*cannot init font engine*/
	if (SA2DR_InitFontEngine(ifce) != M4OK) {
		FT_Delete(ifce);
		return;
	}
	sr->font_engine = ifce;
}

static M4Err SA2DR_LoadRenderer(VisualRenderer *vr, SceneRenderer *compositor)
{
	Render2D *sr;
	if (vr->user_priv) return M4BadParam;

	sr = malloc(sizeof(Render2D));
	if (!sr) return M4OutOfMem;
	memset(sr, 0, sizeof(Render2D));

	sr->compositor = compositor;

	sr->strike_bank = NewChain();
	sr->surfaces_2D = NewChain();

	sr->top_effect = malloc(sizeof(RenderEffect2D));
	memset(sr->top_effect, 0, sizeof(RenderEffect2D));
	sr->top_effect->sensors = NewChain();
	sr->sensors = NewChain();
	
	/*and create main surface*/
	sr->surface = NewVisualSurface2D();
	sr->surface->GetSurfaceAccess = R2D_GetSurfaceAccess;
	sr->surface->ReleaseSurfaceAccess = R2D_ReleaseSurfaceAccess;

	sr->surface->DrawBitmap = R2D_DrawBitmap;
	sr->surface->SupportsFormat = R2D_SupportsFormat;
	sr->surface->render = sr;
	sr->surface->pixel_format = 0;
	ChainAddEntry(sr->surfaces_2D, sr->surface);

	sr->zoom = sr->scale_x = sr->scale_y = 1.0;
	vr->user_priv = sr;

	/*load options*/
	//sr->top_effect->trav_flags |= TF_RENDER_DIRECT;
	sr->scalable_zoom = 1;
	sr->enable_yuv_hw = 0;
	return M4OK;
}

#ifdef DANAE
SR_SetRenderingSession(void *sr, void*session)
{
	((SceneRenderer*)sr)->danae_session = session;
}
#endif

LPSCENERENDER SR_NewStandaloneRenderer()
{
	M4GLConfig cfg, *gl_cfg;
	LPSCENERENDER tmp;
	SAFEALLOC(tmp, sizeof(SceneRenderer))
	SAFEALLOC(tmp->user, sizeof(M4User))

	tmp->visual_renderer = NewVisualRenderer();

	memset(&cfg, 0, sizeof(cfg));
	cfg.double_buffered = 1;
	gl_cfg = tmp->visual_renderer->bNeedsGL ? &cfg : NULL;

	tmp->video_out = NewVideoOutput();
	tmp->video_out->evt_cbk_hdl = tmp;
	tmp->video_out->on_event = NULL;

	tmp->r2d = M4_LoadRenderer();

	/*and init*/
	if (SA2DR_LoadRenderer(tmp->visual_renderer, tmp) != M4OK) {
		tmp->video_out->Shutdown(tmp->video_out);
		free(tmp);
		return NULL;
	}

	tmp->mx = NewMutex();
	tmp->textures = NewChain();
	tmp->frame_rate = 30.0;	
	tmp->frame_duration = 33;
	tmp->time_nodes = NewChain();
	tmp->events = NewChain();
	tmp->ev_mx = NewMutex();
	
	SR_ResetFrameRate(tmp);	
	
	/*set font engine if any*/
	SA2DR_SetFontEngine(tmp);
	
	tmp->extra_scenes = NewChain();
	tmp->base_curve_resolution = DEFAULT_CURVE_RESOLUTION;
	tmp->interaction_level = M4_InteractNormal | M4_InteractInputSensor;
	tmp->antiAlias = M4_AL_All;
	return tmp;
}
