---------------------------colores----------------------------------------------
rojo=Color.new(255,0,0)
red=Color.new(128,0,0)
verde=Color.new(0,255,0)
green=Color.new(0,128,0)
azul=Color.new(0,0,255)
blue = Color.new(58,174,255)
amarillo=Color.new(255,255,0)
blanco=Color.new(255,255,255)
negro=Color.new(0,0,0)
rosa=Color.new(255,0,255)
gris=Color.new(128,128,128)
white = Color.new(255, 255, 255)
black = Color.new(0,0,0)
transp=Color.new(0,0,0,0)
---------------offscrens--------------------------------------------------------
offscreen = Image.createEmpty(480, 272)
offscreen:clear(transp)
offscreen2 = Image.createEmpty(480, 272)
offscreen2:clear(transp)
offscreen3 = Image.createEmpty(480, 41)
offscreen3:clear(transp)
offscreen4 = Image.createEmpty(480, 41)
offscreen4:clear(transp)

function musica()
	local opcion=pintar_menu({"Open","Pause","Resume","Stop"})
	if (opcion==1) then
		dire,file=menu_dir("/",{"UNI", "IT", "XM", "S3M", "MOD", "MTM", "STM", "DSM", "MED", "FAR", "ULT", "669"})
		if (file~="") then
			graphicsPrintln("Reproduciendo: " .. file, green)
			local md_diractual=System.currentDirectory(dire)
			Music.playFile(file,true)
			System.currentDirectory(md_diractual)
		end
	elseif (opcion==2) then
		Music.pause()
	elseif (opcion==3) then
		Music.resume()
	else
		Music.stop()
	end
end


function menu_dir(md_dir,md_filter,md_verdir)
	md_dir=md_dir or System.currentDirectory()
	md_direct=listdir(md_dir,md_filter,md_verdir)
	local md_diractual=System.currentDirectory(md_dir)
	local md_dir=System.currentDirectory()
	local i=1
	local seleccion=1
	local resultado=nil
	while true do
		local controles=Controls.read()
		screen:clear(negro)
		screen:print(10, 10,"Directorio Actual=" .. md_dir, blanco)
		for i=1,table.getn(md_direct) do
			if (seleccion==i) then
				screen:print(80,130+(i-seleccion)*10,"->",azul)
			end
			screen:print(100,130+(i-seleccion)*10,md_direct[i].name,blanco)
		end
		if (ant_controles~=controles) then
			ant_controles=controles
			if controles:up() then
				seleccion=seleccion-1
				if seleccion<1 then
					seleccion=table.getn(md_direct)
				end
			end
			if controles:down() then
				seleccion=seleccion+1
				if seleccion>table.getn(md_direct) then
					seleccion=1
				end
			end
			if controles:circle() then
				System.sleep(200)
				if (md_direct[seleccion].directory) then
					resultado2,resultado=menu_dir(md_dir .. "/" .. md_direct[seleccion].name,md_filter)
				else
					resultado=md_direct[seleccion].name
					resultado2=System.currentDirectory()
				end
				break
			end
			if controles:cross() then System.sleep(200) return "","" end
		end
		screen.flip()
	end
	System.currentDirectory(md_diractual)
	return resultado2,resultado
end

function listdir(ld_dir,ld_filter, ld_verdir)
	ld_dir=ld_dir or System.currentDirectory()
	ld_antdir=System.currentDirectory(ld_dir)
	ld_direct=System.listDirectory()
	local ld_direct2={}
	local i=1
--	ld_filter=nil
	if (ld_filter) then
		for index, file in ld_direct do
			if (file.directory~=true) then
				j=string.find(file.name, ".", 1, true)
				if (j~=nil) then
					for ext=1,table.getn(ld_filter) do
						if (string.lower(string.sub(file.name,j+1,string.len(file.name)))==string.lower(ld_filter[ext])) then
							ld_direct2[i]=file
							i=i+1
						end
					end
				end
			else
					if (ld_verdir~=false) then
						ld_direct2[i]=file
						i=i+1
					end
			end
		end
	else
		ld_direct2=ld_direct
	end
	System.currentDirectory(ld_antdir)
	return ld_direct2
end
function gethour()
	local hora = os.date("*t", os.time())
	local horas = hora.hour
	local minutos = hora.min
	local segundos = hora.sec
	if (minutos<10) then minutos= "0" .. minutos end
	if (segundos<10) then segundos= "0" .. segundos end
	return horas .. ":" .. minutos .. ":" .. segundos
end

function Controls:analogmove()
	local x = self:analogX()  
	local y = self:analogY()
	if (x<-100 or x>100 or y<-100 or y>100) then
		return true
	else
		return false
	end
end



--------------------------------------------------------------------------------
---------codificacion en base64-------------------------------------------------
---------recibe un texto--------------------------------------------------------
---------y devuelve el texto codificado-----------------------------------------
---------string b64_encode(string)----------------------------------------------
---------ejemplo--codific=b64_encode("password")--------------------------------
--------------------------------------------------------------------------------
function b64_encode(b64_texto)
	b64_texto=b64_texto or ""
	b64_texto=tostring(b64_texto)
	local i=1
	local tabla="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	local letra=""
	local resultado=""
	for i=1,string.len(b64_texto) do
		letra=letra..dectobin(string.byte(b64_texto,i),8)
	end
	i=1
	while (i<string.len(letra)-1) do
		resultado=resultado..string.sub(tabla,bintodec(string.sub(letra,i,i+5))+1,bintodec(string.sub(letra,i,i+5))+1)
		i=i+6
	end
	return resultado
end
function b64_decode(b64_texto)
	b64_texto=b64_texto or ""
	b64_texto=tostring(b64_texto)
	local resultado=""
	local tabla="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	local i=1
	local letra=""
	for i=1,string.len(b64_texto) do
		letra=letra..dectobin(string.find(tabla,string.sub(b64_texto,i,i))-1,6)
	end
	i=1
	while (i<string.len(letra)-1) do
		resultado=resultado..string.char(bintodec(string.sub(letra,i,i+7)))
		i=i+8
	end
	return resultado
end
--------------------------------------------------------------------------------
--------convertir de decimal a binario------------------------------------------
--------recibe un numero(entero positivo) y la cantidad de bits a usar----------
--------devuelve un string con el numero en binario-----------------------------
--------string dectobin(int)----------------------------------------------------
--------ejemplo---nbinario=dectobin(10,8)---------------------------------------
--------------------------------------------------------------------------------
function dectobin(dtb_numero,dtb_bits)
	dtb_numero=dtb_numero or 0
	dtb_numero=tonumber(dtb_numero)
	local binario=""
	local binario2=""
	local i=1
	dtb_bits=dtb_bits or 0
	local bit
	while dtb_numero>1 do
		bit=string.sub(tostring(math.mod(dtb_numero,2)),1,1)
		dtb_numero=dtb_numero/2
		binario=binario..bit
	end
	if (dtb_numero<2) then binario=binario..string.sub(tostring(dtb_numero),1,1) end
	if (dtb_bits>0) then
		while (string.len(binario) < dtb_bits) do
			binario=binario.."0"
		end
	end
	for i=1, string.len(binario) do
		binario2=binario2..string.sub(binario,string.len(binario)+1-i,string.len(binario)+1-i)
	end
	if (dtb_bits>0) then
		binario2=string.sub(binario2,string.len(binario2)-dtb_bits+1,string.len(binario2))
	end
	return binario2
end
--------------------------------------------------------------------------------
--------convertir de binario a decimal------------------------------------------
--------recibe un numero binario(entero positivo)-------------------------------
--------devuelve el numero en decimal-------------------------------------------
--------int bintodec(string)----------------------------------------------------
--------int bintodec(int)-------------------------------------------------------
--------ejemplo---numero=bintodec("1101")---------------------------------------
--------------------------------------------------------------------------------
function bintodec(btd_numero)
	btd_numero=btd_numero or ""
	btd_numero=tostring(btd_numero)
	local i=0
	local numero=0
	local num_long=string.len(btd_numero)
	for i=1,num_long do
		if (tonumber(string.sub(btd_numero,num_long-i,num_long-i))==1) then
			numero=numero+math.pow(2,i)
		end
	end
	if (tonumber(string.sub(btd_numero,num_long,num_long))==1) then
		numero=numero+1
	end
	return numero
end
--------------------------------------------------------------------------------
--------pinta un menu-----------------------------------------------------------
----------int pintar_menu(array, string)----------------------------------------
-------devuelve el elemento seleccionado----------------------------------------
-------recibe elementos en un array---------------------------------------------
--por ejemplo------menuseleccion=pintar_menu({"opcion1","opcion2"},"selecciona")-
--------------------------------------------------------------------------------
function pintar_menu(pmenu_opciones, pmenu_msg)
	if (pmenu_opciones==nil) then return 0 end
	local i=1
	local seleccion=1
	local ant_controles=Controls.read
	while true do
		local controles=Controls.read()
		screen:clear(negro)
		if (pmenu_msg~=nil) then screen:print(1, 1, pmenu_msg, blanco) end
		for i=1,table.getn(pmenu_opciones) do
			if (seleccion==i) then
				screen:print(80,136+(i-seleccion)*10,"->",azul)
			end
			screen:print(100,136+(i-seleccion)*10,pmenu_opciones[i],blanco)
		end
		if (ant_controles~=controles) then
			ant_controles=controles
			if controles:up() then
				seleccion=seleccion-1
				if seleccion<1 then
					seleccion=table.getn(pmenu_opciones)
				end
			end
			if controles:down() then
				seleccion=seleccion+1
				if seleccion>table.getn(pmenu_opciones) then
					seleccion=1
				end
			end
			if controles:circle() then System.sleep(200) return seleccion end
			if controles:cross() then System.sleep(200) return 0 end
		end
		screen.flip()
	end
end
--------------------------------------------------------------------------------
--------------teclado-----------------------------------------------------------
--------------llamar init_teclado() para inizializar el teclado-------------------
--------------cuando se quiera usar e teclado-----------------------------------
--------------hacer una llamada del estilo de-----------------------------------
--------------texto=teclado(texto)----------------------------------------------
--------------------------------------------------------------------------------
function init_teclado()
tec_imagen = Image.createEmpty(480, 40)
tec_imagen:clear(negro)
tec_teclas1="1234567890<>qwertyuiop-+asdfghjkl@^_zxcvbnm,."
tec_teclas2="!`'#$%&/()=?QWERTYUIOP[]ASDFGHJKL*{}ZXCVBNM;:"
tec_teclas=tec_teclas1
tec_porlinea=12
tec_atajos1 = {shorts[1], shorts[2], shorts[3], shorts[4], shorts[5], shorts[6], shorts[7]} or {"Hola","Adios","Si","No","XD","ktal","tengo"}
tec_atajos2 = {shorts[8], shorts[9], shorts[10], shorts[11], shorts[12], shorts[13], shorts[14]} or {"mogu","quiero","ya","me voy",":)","linux","dame"}
tec_atajos=tec_atajos1
tec_num=1
tec_color=blanco
tec_atajo=false
tec_controles=Controls.read()
end

function teclado(tec_texto,tec_color1)
	local i=1
	local j=1
	local tec_y=0
	local tec_x=20
	tec_color1=tec_color1 or blanco
	for i=1,string.len(tec_teclas) do
		if (i==tec_num) then
			tec_color=rojo
		else
			tec_color=tec_color1
		end
		tec_imagen:print(tec_x,tec_y,string.sub(tec_teclas,i,i),tec_color)
		tec_x=tec_x+10
		j=j+1
		if (j>tec_porlinea) then
			j=1
			tec_x=20
			tec_y=tec_y+10
		end
	end
	local controles=Controls.read()
	if controles:analogmove() then
		if (tec_teclas==tec_teclas1) then
			tec_teclas=tec_teclas2
			tec_atajos=tec_atajos2
		else
			tec_teclas=tec_teclas1
			tec_atajos=tec_atajos1
		end
		System.sleep(100)
	end
	if (tec_controles~=controles) then
	tec_controles=controles
	if (tec_atajo~=true) then
		if controles:right() then
			tec_num=tec_num+1
			if (tec_num>string.len(tec_teclas)) then
				tec_num=1
			end
		end
		if controles:left() then
			tec_num=tec_num-1
			if (tec_num<1) then
				tec_num=string.len(tec_teclas)
			end
		end
		if controles:up() then
			tec_num=tec_num-tec_porlinea
			if (tec_num<1) then
				tec_num=tec_num+tec_porlinea*4
			end
		end
		if controles:down() then
			tec_num=tec_num+tec_porlinea
			if (tec_num>string.len(tec_teclas)) then
				tec_num=tec_num-tec_porlinea*4
			end
		end
		if controles:circle() then
			tec_texto=tec_texto..string.sub(tec_teclas,tec_num,tec_num)
		end
		if controles:cross() then
			tec_texto=string.sub(tec_texto,1,string.len(tec_texto)-1)
		end
		if controles:triangle() then
			tec_texto=tec_texto.." "
		end
	end
		if controles:select() then
			if controles:up() then
				tec_texto=tec_texto .. tec_atajos[1]
			end
			if controles:down() then
				tec_texto=tec_texto .. tec_atajos[2]
			end
			if controles:left() then
				tec_texto=tec_texto .. tec_atajos[3]
			end
			if controles:right() then
				tec_texto=tec_texto .. tec_atajos[4]
			end
			if controles:triangle() then
				tec_texto=tec_texto .. tec_atajos[5]
			end
			if controles:circle() then
				tec_texto=tec_texto .. tec_atajos[6]
			end
			if controles:cross() then
				tec_texto=tec_texto .. tec_atajos[7]
			end
			tec_atajo=true
		else
			tec_atajo=false
		end
	end
	if (tec_atajo) then
		tec_imagen:print(190, 0, "  " .. tec_atajos[1] .. "         " .. tec_atajos[5], tec_color1)
		tec_imagen:print(190, 10, tec_atajos[3] .. "     " .. tec_atajos[4] .. "         " .. tec_atajos[6], tec_color1)
		tec_imagen:print(190, 20, "  " .. tec_atajos[2] .. "         " .. tec_atajos[7], tec_color1)
	else
		tec_imagen:print(290, 0, textos.msg_insert, tec_color1)
		tec_imagen:print(290, 10, textos.msg_space, tec_color1)
		tec_imagen:print(290, 20, textos.msg_del, tec_color1)
	end

	screen:blit(0,232,tec_imagen)
	tec_imagen:clear(transp)
	return tec_texto
end
--------------------------------------------------------------------------------
-----permite entar un texto mientras el programa espera(como scanf en C)--------
-----necesita las funciones init_teclado() y teclado(texto)---------------------
-----string input_text([string])------------------------------------------------
-----ejemplo texto=input_text("Entra un nombre")--------------------------------
--------------------------------------------------------------------------------

function input_text(tec_pregunta,tec_aceptar,tec_pregunta_x,tec_pregunta_y)
tec_aceptar=tec_aceptar or "[]=Aceptar"
tec_pregunta=tec_pregunta or ""
tec_pregunta_x=tec_pregunta_x or 50
tec_pregunta_y=tec_pregunta_y or 136
local texto=""
	while true do
		screen:clear(negro)
		texto=teclado(texto)
		screen:print(tec_pregunta_x,tec_pregunta_y,tec_pregunta .. texto.."_", blanco)
		screen:print(282,260,tec_aceptar,blanco)
		screen.flip()
		if Controls.read():square() then System.sleep(200) return texto end
	end
end

--------------------------fuentes-----------------------------------------------
--------------------------fuentes-----------------------------------------------
fps_tiempo=Timer.new()
function fps()
	fps_tiempo2=fps_tiempo:stop()
	fps_tiempo=Timer.new()
	return (1/fps_tiempo2)*1000
end
---------------------------distancia por pitagoras------------------------------
function math.distancia(xa,ya,xb,yb)
    xc=math.abs(xa-xb)
	yc=math.abs(ya-yb)
	dist=math.sqrt((xc*xc)+(yc*yc))
	return dist	
end
--------------------------------------------------------------------------------
----------pinta un texto en la parte inferior de la pantalla--------------------
--------------------------------------------------------------------------------
function stext(sc_texto,sc_color)
	sc_color=sc_color or blanco
	local proportional = Font.createProportional()
	proportional:setPixelSizes(0, 14)

       if (i>100) then
	   screen:fontPrint(proportional, 25, 240-3,string.sub(sc_texto,1,50),sc_color)
	   screen:fontPrint(proportional, 25, 255-3,string.sub(sc_texto,51,100),sc_color)
	   screen:fontPrint(proportional, 25, 270-3,string.sub(sc_texto,101,i),sc_color)
    elseif (i>50) then
	   screen:fontPrint(proportional, 25, 255-3,string.sub(sc_texto,1,50),sc_color)
	   screen:fontPrint(proportional, 25, 270-3,string.sub(sc_texto,51,i),sc_color)
    else
	   screen:fontPrint(proportional, 25, 270-3,string.sub(sc_texto,1,i),sc_color)
    end
    screen.waitVblankStart()
if (controls:circle() and string.len(sc_texto)>i) then
    i=i+1
else
	screen.waitVblankStart(5)
end
	screen.flip()
	screen:clear(negro)
    screen:blit(0, 0, fondo)
    screen:fillRect(0,225,480,47,gris)
---    screen:blit(0, 225, caja)
    controls=Controls.read()
if (controls:select()) then
    i=0
end

if (string.len(sc_texto)>i) then
    i=i+1
    stext(sc_texto,sc_color)
else
	screen.waitVblankStart()
end
end
--------------------------------------------------------------------------------
-- gira una imagen 1 para espejo vertical otro valor para espejo horizontal-----
--------------------------------------------------------------------------------
function Image:girar(dir)
  dir = dir or 1		   -- clockwise by default
					  -- cw ~= 1 -> counter-clockwise
  local x
  local y
  local w = self:width()
  local h = self:height()
  local result = Image.createEmpty(w, h)
  for x = 1, w-1 do
    for y = 1, h-1 do
	 if dir == 1 then
	   result:pixel(w-x,y, self:pixel(x,y))
	 else
	   result:pixel(x,h-y, self:pixel(x,y))
	 end
    end
  end
  return result
end


----------------------------------------------------------------------------
------------funciones-wifi--------------------------------------------------
----------------------------------------------------------------------------
y=0
x=0

-- function clear()
-- 	offscreen2:clear(negro)
-- end

function chooseNetwork(lid)
	opcion = 0
	Wlan.init()
	configs = Wlan.getConnectionConfigs()
	while (opcion==0) do
		opcion = pintar_menu(configs, textos.wlan_choose)
	end
	graphicsPrintln(textos.wlan_init, blue, true)
	graphicsPrintln(textos.wlan_init2, white, true)
	graphicsPrintln(textos.wlan_init3, white, true)
	graphicsPrintln(textos.wlan_wait, verde, true)
	graphicsPrintln(textos.wlan_wait2, verde, true)
	Wlan.useConnectionConfig(opcion)
	while true do
		ipAddress = Wlan.getIPAddress()
		if ipAddress then break end
		if Controls.read():start() then break end
		System.sleep(100)
	end
	graphicsPrintln(textos.wlan_pspip .. ipAddress, verde, true)
end

-- function chooseNetwork(lid)
-- 	Wlan.term()
-- 	selected=1
-- 	chosen=false
-- 	state=0
-- 	quit=false
-- 	Wlan.init()
-- 	configs = Wlan.getConnectionConfigs()
-- 	screen:clear(negro)
-- 	screen:print(100, 260, textos.sock_cancel, rojo)
-- 	-- init WLAN and choose connection config
-- 	if (lid == 0) then
-- 		repeat
-- 			getState()
-- 			updateConnections()
-- 			if quit then break end
-- 		until state==1
-- 		clear()
-- 		screen:clear(negro)
-- 		graphicsPrintln(textos.wlan_init, blue, true)
-- 		graphicsPrintln(textos.wlan_init2, white, true)
-- 		graphicsPrintln(textos.wlan_init3, white, true)
-- 		screen:blit(0, 0, offscreen2)
-- 		screen.waitVblankStart()
-- 		screen.flip()
-- 		Wlan.init()
-- 		if not quit then
-- 			Wlan.useConnectionConfig(selected)
-- 		end
-- 	else
-- 		Wlan.init()
-- 		Wlan.useConnectionConfig(lid)
-- 	end
-- 	-- start connection and wait until it is connected
-- 	graphicsPrintln(textos.wlan_wait, verde, true)
-- 	graphicsPrintln(textos.wlan_wait2, verde, true)
-- 	while true do
-- 		ipAddress = Wlan.getIPAddress()
-- 		if ipAddress then break end
-- 		if Controls.read():start() then break end
-- 		System.sleep(100)
-- 	end
-- 	graphicsPrintln(textos.wlan_pspip .. ipAddress, verde, true)
-- end

function updateConnections()
	local i=1
	for key, value in configs do
		offscreen2:print(13,i*8 + 20,"  [".. i .. "]: " .. value, white)
		screen:blit(0, 0, offscreen2)
		screen.waitVblankStart()
		screen.flip()
		screen:clear(negro)
		if i == selected then
			offscreen2:print(0,i*8 + 20,"->",blue)
		else
			offscreen2:print(0,i*8 + 20,"->",black)
		end
		i = i+1
	end
end

function getState()
  offscreen2:print(0, 0, textos.wlan_choose, white)
  screen:blit(0, 0, offscreen2)
  screen.waitVblankStart()
  screen.flip()
  lim=table.getn(configs)
  local pad = Controls.read()
  if pad ~= oldPad then
    if pad:circle() then
      state=1
    elseif pad:start() then
      quit = true
    elseif pad:down() then
      if selected < lim then
        selected = selected+1
      end
    elseif pad:up() then
      if selected > 1 then
        selected = selected-1
      end
    end
  end
  oldPad = pad
  return 0
end
-------------------------------------------------------------------------
----------------consola de texto-----------------------------------------
-------------------------------------------------------------------------
gPx=5
gPy=5
gPy2=0
function graphicsPrint(gPtext, gPcolor, gPmostrar,gPiconos)
	gPcolor = gPcolor or blanco
	gPmostrar=gPmostrar or false
	local encontrado=false
	gPny=0
	gPi=1
	local n_icono=""
	if (running_plugin) then
		offscreen3:print(10, gPy2, gPtext, gPcolor)
		gPy2=gPy2+8
			if (gPy2 > 33) then
				offscreen4:clear(transp)
				offscreen4:blit(0, 0, offscreen3)
				offscreen3:clear(transp)
				offscreen3:blit(0, -8, offscreen4)
				gPy2=gPy2-8
			end
	else
		while gPi <= string.len(gPtext) do
			if (gPiconos) then
				for index, icono in gPiconos do
					if (icono.directory~=true) then
						n_icono=string.sub(icono.name,1,-5)
						encontrado=string.find(string.lower(gPtext), string.lower(n_icono), gPi,true)
						if (encontrado==gPi) then
							local gPicono=Image.load("./icons/" .. icono.name)
							gPtext=string.sub(gPtext,1,encontrado-1) .. string.sub(gPtext,encontrado + string.len(n_icono),string.len(gPtext))
							gPi=gPi-1
							offscreen:blit(gPx, gPy, gPicono)
							gPx=gPx+gPicono:width()
							if (gPny<gPicono:height()) then
								gPny=gPicono:height()
							end
						end
					end
				end
			end
			char = string.sub(gPtext, gPi, gPi)
			if (gPx>340) then
				gPy = gPy + gPny + 8
				gPx = 5
			end
			if (gPy + gPny>200) then
				gPy=gPy - (8+gPny)
				offscreen2:clear(transp)
				offscreen2:blit(0, 0, offscreen)
				offscreen:clear(transp)
				offscreen:blit(0, -(8+gPny), offscreen2)
			end
			if char == "\n" then
				gPy = gPy + gPny + 8
				gPx = 5
			elseif char ~= "\r" then
					offscreen:print(gPx, gPy, char, gPcolor)
					gPx = gPx + 8
			end
			gPi=gPi+1
		end
		if (gPmostrar) then
			screen:clear(negro)
			screen:blit(0, 0, offscreen)
			screen.flip()
		end
	end
end

function graphicsPrintln(gPltext, gPlcolor, gPlmostrar, gPliconos)
	gPlcolor = gPlcolor or blanco
	gPlmostrar = gPlmostrar or false
	gPliconos = gPliconos or nil
	graphicsPrint(gPltext .. "\n", gPlcolor, gPlmostrar, gPliconos)
end

-------------------------------------------------------------------------
------------------------funciones ficheros-------------------------------
-------------------------------------------------------------------------

function fileSize(file)
	if file then
		local current = file:seek()      -- get current position
		local size = file:seek("end")    -- get file size
		file:seek("set", current)        -- restore position
		return size
	end
end

function friendlySize(size)
	if size >= 1048576 then				-- 1,048,576b = 1 MB
		return string.format("%.1f",(size / 1048576)) .. " MB"
	elseif size >= 1024 then				-- 1024b = 1 kB
		return string.format("%.0f",(size / 1024)) .. " kB"
	else 
		return size .. " bytes"
	end
end

function fileExists(file)
	t, msg = io.open(file, "r")
     if not t then return false end
	return true
end


-------------------------------------------------------------------------
function math.round(num, dp)
  local mult = 10^(dp or 0)
  return math.floor(num  * mult + 0.5) / mult
end

function Image:drawEllipse(x1,y1, x2,y2, segments, color)
  local a = (x2-x1) / 2; local x0 = (x2+x1) / 2
  local b = (y2-y1) / 2; local y0 = (y2+y1) / 2
  local PI2 = math.pi * 2
  x1, y1 = x0, y0 + b
  for i = 1, segments do
    x2 = math.round(x0 + a * math.sin(PI2*i/segments))
    y2 = math.round(y0 + b * math.cos(PI2*i/segments))
    self:drawLine(x1,y1, x2,y2, color)
    x1,y1 = x2,y2
  end
end

function Image:magnify(mag)
  mag = mag or 2		 -- 2 times in size by default
  local w = self:width()  
  local h = self:height()
  local result = Image.createEmpty(mag*w, mag*h)
  for x = 0, w-1 do
    for y = 0, h-1 do
	 result:fillRect(mag*x, mag*y, mag,mag, self:pixel(x,y))
    end
  end
  return result
end

function Image:caption(x,y, text, color, fontsize)
  fontsize = fontsize or 1
  local w = string.len(text)
  local temp = Image.createEmpty(8 * w, 8)
  temp:print(0,0, text, color)
  if fontsize > 1 then 
    temp = temp:magnify(fontsize)
  end
  self:blit(x,y, temp)
end

function Image:rotate(cw)
  cw = cw or 1		   -- clockwise by default
					  -- cw ~= 1 -> counter-clockwise
  local w = self:width()
  local h = self:height()
  local result = Image.createEmpty(h, w)
  for x = 0, w-1 do
    for y = 0, h-1 do
	 if cw == 1 then
	   result:pixel(h-y-1, x, self:pixel(x,y))
	 else
	   result:pixel(y, w-x-1, self:pixel(x,y))
	 end
    end
  end
  return result
end


--------------------  Credits ---------------------
-- Davgav		for b64_encode(b64_texto)
-- Davgav		for dectobin(dtb_numero,[dtb_bits])
-- Davgav		for bintodec(btd_numero)
-- Davgav		for pintar_menu(pmenu_opciones)
-- Davgav		for init_teclado()
-- Davgav		for teclado(tec_texto)
-- Davgav		for input_text(tec_pregunta,[tec_aceptar],[tec_pregunta_x],[tec_pregunta_y]) it needs init_teclado() and teclado(text)
-- Davgav		for math.distancia(x1,y1,x2,y2)
-- Davgav		for image:girar([direction]) left to right by default
-- httpd 		for chooseNetwork(lid) if lid=0 shows a menu for choice network
-- httpd		for graphicsPrintln(text, [color], [mostrar]) colo
