--[[
Copyright (c) 2006-2012 LOVE Development Team

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
--]]

do

	local vera_ttf = love.filesystem.newFileData([[
[encoded data, 90354 characters]
	]], "Vera.ttf", "base64")

	local _newFont = love.graphics.newFont
	love.graphics.newFont = function(font, size)
		if type(font) == "number" or not font then
			size = font
			font = vera_ttf
		end
		return _newFont(font, size or 12)
	end

	love.graphics.setNewFont = function(...)
		local font = love.graphics.newFont(...)
		love.graphics.setFont(font)
		return font
	end

	local _getFont = love.graphics.getFont
	love.graphics.getFont = function(...)
		local font = _getFont()
		if not font then
			font = love.graphics.setNewFont(12)
		end
		love.graphics.getFont = _getFont
		return font
	end

	local _print = love.graphics.print
	love.graphics.print = function (...)
		love.graphics.getFont() -- make sure we have a font
		love.graphics.print = _print
		love.graphics.print(...)
	end

	local _printf = love.graphics.printf
	love.graphics.printf = function (...)
		love.graphics.getFont() -- make sure we have a font
		love.graphics.printf = _printf
		love.graphics.printf(...)
	end

	-- PIXEL EFFECTS
	local GLSL_HEADER_LINE_COUNT = 6
	local GLSL_HEADER = [[#version 120
	#define number float
	#define Image sampler2D
	#define extern uniform
	#define Texel texture2D
	uniform sampler2D _tex0_;]]
	local GLSL_FOOTER = [[void main() {
		// fix weird crashing issue in OSX when _tex0_ is unused within effect()
		float dummy = texture2D(_tex0_, vec2(.5)).r;
		gl_FragColor = effect(gl_Color, _tex0_, gl_TexCoord[0].xy, gl_FragCoord.xy);
	}]]
	function love.graphics._effectCodeToGLSL(code)
		return table.concat{GLSL_HEADER, "\n", code, GLSL_FOOTER}
	end

	function love.graphics._transformGLSLErrorMessages(message)
		if not message:match("Cannot compile shader") then return message end
		local lines = {"Cannot compile shader:"}
		for l in message:gmatch("[^\n]+") do
			-- nvidia compiler message:
			-- 0(<linenumber>) : error/warning [NUMBER]: <error message>
			local linenumber, what, message = l:match("^0%((%d+)%)%s*:%s*(%w+)[^:]+:%s*(.+)$")
			if not linenumber then
				-- ati compiler message:
				-- ERROR 0:<linenumber>: error/warning(#[NUMBER]) [ERRORNAME]: <errormessage>
				linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$")
			end
			if linenumber and what and message then
				linenumber = linenumber - GLSL_HEADER_LINE_COUNT
				lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message)
			end
		end
		-- did not match any known error messages
		if #lines == 1 then return message end
		return table.concat(lines, "\n")
	end

	-- helper to transform a matrix from {{a,b,c}, {d,e,f}, ...} to
	-- {a, b, c, d, e, f, ...}
	local function flattenMatrices(mat, ...)
		if not mat then return end

		local ret,l = {}, 1
		ret.dimension = #mat

		for i = 1,#mat do
			for k = 1,#mat[i] do
				ret[l], l = tonumber(mat[i][k]), l+1
			end
		end

		return ret, flattenMatrices(...)
	end

	-- automagic uniform setter
	local function pixeleffect_dispatch_send(self, name, value, ...)
		if type(value) == "number" then         -- scalar
			self:sendFloat(name, value, ...)
		elseif type(value) == "userdata" and value:typeOf("Image") then
			self:sendImage(name, value)
		elseif type(value) == "userdata" and value:typeOf("Canvas") then
			self:sendCanvas(name, value)
		elseif type(value) == "table" then      -- vector or matrix
			if type(value[1]) == "number" then
				self:sendFloat(name, value, ...)
			elseif type(value[1]) == "table" then
				self:sendMatrix(name, flattenMatrices(value, ...))
			else
				error("Cannot send value (unsupported type: {"..type(value[1]).."}).")
			end
		else
			local t = type(value)
			if t == "userdata" and value.type then t = value.type end
			error("Cannot send value (unsupported type: "..t..").")
		end
	end

	local newPixelEffect = love.graphics.newPixelEffect
	function love.graphics.newPixelEffect(code)
		love.graphics.newPixelEffect = function(code)
			if love.filesystem and love.filesystem.exists(code) then
				code = love.filesystem.read(code)
			end
			return newPixelEffect(code)
		end

		local effect = love.graphics.newPixelEffect(code)
		local meta = getmetatable(effect)
		meta.send = pixeleffect_dispatch_send
		return effect
	end

end
