--[[
Copyright (c) 2006-2013 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 table_concat = table.concat
	local type = type

	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


	-- SHADERS

	local GLSL_VERSION = "#version 120"
	
	local GLSL_SYNTAX = [[
#define number float
#define Image sampler2D
#define extern uniform
#define Texel texture2D
#define love_Canvases gl_FragData]]

	local GLSL_UNIFORMS = [[
#define ModelViewMatrix gl_ModelViewMatrix
#define ProjectionMatrix gl_ProjectionMatrix
#define ModelViewProjectionMatrix gl_ModelViewProjectionMatrix
#define NormalMatrix gl_NormalMatrix
uniform sampler2D _tex0_;]]

	local GLSL_VERTEX = {
		HEADER = [[
#define VERTEX

#define VertexPosition gl_Vertex
#define VertexTexCoord gl_MultiTexCoord0
#define VertexColor gl_Color

#define VaryingTexCoord gl_TexCoord[0]
#define VaryingColor gl_FrontColor]],

		FOOTER = [[
void main() {
	VaryingTexCoord = VertexTexCoord;
	VaryingColor = VertexColor;
	gl_Position = position(ModelViewProjectionMatrix, VertexPosition);
}]],
	}

	local GLSL_PIXEL = {
		HEADER = [[
#define PIXEL

#define VaryingTexCoord gl_TexCoord[0]
#define VaryingColor gl_Color]],

		FOOTER = [[
void main() {
	// fix crashing issue in OSX when _tex0_ is unused within effect()
	float dummy = texture2D(_tex0_, vec2(.5)).r;
	gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, gl_FragCoord.xy);
}]],

		FOOTER_MULTI_CANVAS = [[
void main() {
	// fix crashing issue in OSX when _tex0_ is unused within effect()
	float dummy = texture2D(_tex0_, vec2(.5)).r;
	effects(VaryingColor, _tex0_, VaryingTexCoord.st, gl_FragCoord.xy);
}]],
	}

	local function createVertexCode(vertexcode)
		local vertexcodes = {
			GLSL_VERSION,
			GLSL_SYNTAX, GLSL_VERTEX.HEADER, GLSL_UNIFORMS,
			"#line 0",
			vertexcode,
			GLSL_VERTEX.FOOTER,
		}
		return table_concat(vertexcodes, "\n")
	end

	local function createPixelCode(pixelcode, is_multicanvas)
		local pixelcodes = {
			GLSL_VERSION,
			GLSL_SYNTAX, GLSL_PIXEL.HEADER, GLSL_UNIFORMS,
			"#line 0",
			pixelcode,
			is_multicanvas and GLSL_PIXEL.FOOTER_MULTI_CANVAS or GLSL_PIXEL.FOOTER,
		}
		return table_concat(pixelcodes, "\n")
	end

	local function isVertexCode(code)
		return code:match("vec4%s*position%(") ~= nil
	end

	local function isPixelCode(code)
		if code:match("vec4%s*effect%(") then
			return true
		elseif code:match("void%s*effects%(") then -- render to multiple canvases simultaniously
			return true, true
		else
			return false
		end
	end

	function love.graphics._shaderCodeToGLSL(arg1, arg2)
		local vertexcode, pixelcode
		local is_multicanvas = false -- whether pixel code has "effects" function instead of "effect"
		
		if arg1 then
			local s = arg1:gsub("\r\n\t", " ") -- convert whitespace to spaces for parsing
			s = s:gsub("(%w+)(%s+)%(", "%1(") -- convert "func ()" to "func()"

			if isVertexCode(s) then
				vertexcode = arg1 -- first arg contains vertex shader code
			end

			local ispixel, isMultiCanvas = isPixelCode(s)
			if ispixel then
				pixelcode = arg1 -- first arg contains pixel shader code
				is_multicanvas = isMultiCanvas
			end
		end
		
		if arg2 then
			local s = arg2:gsub("\r\n\t", " ") -- convert whitespace to spaces for parsing
			s = s:gsub("(%w+)(%s+)%(", "%1(") -- convert "func ()" to "func()"

			if isVertexCode(s) then
				vertexcode = arg2 -- second arg contains vertex shader code
			end

			local ispixel, isMultiCanvas = isPixelCode(s)
			if ispixel then
				pixelcode = arg2 -- second arg contains pixel shader code
				is_multicanvas = isMultiCanvas
			end
		end

		if vertexcode then
			vertexcode = createVertexCode(vertexcode)
		end
		if pixelcode then
			pixelcode = createPixelCode(pixelcode, is_multicanvas)
		end

		return vertexcode, pixelcode
	end

	function love.graphics._transformGLSLErrorMessages(message)
		local shadertype = message:match("Cannot compile (%a+) shader code")
		if not shadertype then return message end
		local lines = {"Cannot compile "..shadertype.." shader code:"}
		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*(.+)$")
				if not linenumber then
					-- OSX compiler message (?):
					-- ERROR: 0:<linenumber>: <errormessage>
					what, linenumber, message = l:match("^(%w+): %d+:(%d+): (.+)$")
				end
			end
			if linenumber and what and message then
				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
end
