
local MAX_MOVES = 0
local LOADED_LEVEL = 0
local TOTAL_MOVES = 0
local MAX_UNLOCKED_LEVEL = 1

local COLS = 10
local ROWS = 10

local CELL_OFF = 0
local CELL_OFF_CLICK = 1
local CELL_ON = 2
local CELL_ON_CLICK = 3
local CELL_TURNING_ON = 4
local CELL_TURNING_OFF = 5

local LEFT_ARROW_CLICK = 0
local RIGHT_ARROW_CLICK = 0

local AUTOTURNER_BAR = 0
local COMPLETE_FOR_WIN = false

local HOME_CLICKED = 0

-- init cells hash table
local CELLS={}
for x=0, COLS-1 do
        CELLS[x]={}
        for y=0, ROWS-1 do
                CELLS[x][y]={}
                CELLS[x][y]['state']=CELL_OFF
                CELLS[x][y]['frame']=0
        end
end

function LoadGameSettings()
        openconfig("enlight.dat", 100)
        TOTAL_MOVES=readconfignumber("options", "maxmoves", 0)
        MAX_UNLOCKED_LEVEL=readconfignumber("options", "unlocked", 1)
        closeconfig()
        -- load last unlocked level
        LoadLevel(MAX_UNLOCKED_LEVEL)
end

function SaveGameSettings()
        openconfig("enlight.dat", 100)
        writeconfignumber("options", "maxmoves", TOTAL_MOVES)
        writeconfignumber("options", "unlocked", MAX_UNLOCKED_LEVEL)
        closeconfig()
end

function DoGame()

        drawimage(IMGBACKGROUND, 0, 0)

        -- handle cells drawing
        local num_off = 0
        for x=0, COLS-1 do
                for y=0, ROWS-1 do
                        
                        local cx = 5 + x *23
                        local cy = 18 + y *23
                        
                        -- draw cell and tell us if its turned off
                        ret = DrawCell(cx, cy, x, y)
                        if ret then  num_off = num_off + 1 end
                end
        end
        
        -- if we turned off all cells, we must celebrate!
        if AUTOTURNER_BAR == 0 and num_off==COLS*ROWS then 
                playsound(SNDCHANGELEVEL)
                AUTOTURNER_BAR = 18 
                COMPLETE_FOR_WIN = true
        elseif AUTOTURNER_BAR == 0 and MAX_MOVES == 0 then
                -- if we reached max moves, animate for level lose
                playsound(SNDGAMEOVER)
                AUTOTURNER_BAR = 18 
                COMPLETE_FOR_WIN = false
        end
         
        
        -- animate for level completed
        if AUTOTURNER_BAR ~= 0 then DoLevelSwitchBar() end
         
        -- draw stats
        DrawNumbers(95,254,PadZero(LOADED_LEVEL, 3))
        DrawNumbers(95,266,PadZero(MAX_MOVES, 3))
        DrawNumbers(95,279,PadZero(TOTAL_MOVES, 3))
        
        -- draw arrows
        DrawArrows()
        
        -- draw home button
        drawimage(IMGHOMEBUTTON, 188, 273, HOME_CLICKED*40, 0, HOME_CLICKED*40+40, imageheight(IMGHOMEBUTTON))

end -- DoGame


function DoLevelSwitchBar()


        if AUTOTURNER_BAR > 0 then
                AUTOTURNER_BAR = AUTOTURNER_BAR + 4
        else
                AUTOTURNER_BAR = AUTOTURNER_BAR - 4
        end
        
        -- which row we should highlight
        local row = math.floor((math.abs(AUTOTURNER_BAR)-18)/23)
        
        -- turn on the cells not yet turned on
        if row < COLS then
                for col=0, COLS-1 do
                        if AUTOTURNER_BAR > 0 then
                                if CELLS[col][row]['state'] == CELL_OFF then
                                        TurnOnCell(col, row)
                                end
                        else
                                if CELLS[col][row]['state'] == CELL_ON then
                                        TurnOffCell(col, row)
                                end
                        end
                end
        
        else
                -- end of level completed animation
                if AUTOTURNER_BAR < 0 then
                        
                        -- we can load now the next level (or the same if we lose)
                        AUTOTURNER_BAR = 0
                        
                        -- go to next level if we win
                        if COMPLETE_FOR_WIN == true then
                                LOADED_LEVEL = LOADED_LEVEL + 1
                                if LOADED_LEVEL > 50 then LOADED_LEVEL=50 end
                                if LOADED_LEVEL > MAX_UNLOCKED_LEVEL then MAX_UNLOCKED_LEVEL = LOADED_LEVEL end
                                
                                -- save settings
                                SaveGameSettings()
                        end
                        
                                
                        playsound(SNDSTART)
                        LoadLevel(LOADED_LEVEL)

                else
                        AUTOTURNER_BAR = -18
                end
        end

	-- if we're losing, draw blended bar on "moves left" section
	if COMPLETE_FOR_WIN == false then
	       blending(130)
	       fillrect(25,266,122, 277, 255,255,0)
	       blending(255)
	end
        
end -- DoWinning


function DrawArrows()
        drawimage(IMGARROWS, 30, 254, LEFT_ARROW_CLICK*12, 0, LEFT_ARROW_CLICK*12+12, 11) 
        drawimage(IMGARROWS, 45, 254, RIGHT_ARROW_CLICK*12, 11, RIGHT_ARROW_CLICK*12+12, 22) 
end


function PadZero(text, num)
        local fin = text
        while string.len(fin) < num do
                fin = "0" .. fin
        end
        return fin
end

function DrawNumbers(x, y, text)
        local sx = x
        for s=0, string.len(text) do
                if string.sub(text, s, s) == "0" then drawimage(IMGNUMBERS, sx, y, 0*7, 0, 0*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "1" then drawimage(IMGNUMBERS, sx, y, 1*7, 0, 1*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "2" then drawimage(IMGNUMBERS, sx, y, 2*7, 0, 2*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "3" then drawimage(IMGNUMBERS, sx, y, 3*7, 0, 3*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "4" then drawimage(IMGNUMBERS, sx, y, 4*7, 0, 4*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "5" then drawimage(IMGNUMBERS, sx, y, 5*7, 0, 5*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "6" then drawimage(IMGNUMBERS, sx, y, 6*7, 0, 6*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "7" then drawimage(IMGNUMBERS, sx, y, 7*7, 0, 7*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "8" then drawimage(IMGNUMBERS, sx, y, 8*7, 0, 8*7+7, imageheight(IMGNUMBERS))
                elseif string.sub(text, s, s) == "9" then drawimage(IMGNUMBERS, sx, y, 9*7, 0, 9*7+7, imageheight(IMGNUMBERS)) end
                sx = sx + 7
        end
end

-- draw cell
-- return true if cell is turned off (used for counting)
function DrawCell(x, y, col, row)
                
        -- draw cell
        local frame = CELLS[col][row]['state']
        if CELLS[col][row]['state'] == CELL_TURNING_ON or CELLS[col][row]['state'] == CELL_TURNING_OFF then
                frame = CELLS[col][row]['frame'] + 4
        end
        
        drawimage(IMGBALLS, x, y, frame*23, 0, frame*23+23, 23)

        -- animate cell if it's animating
        if CELLS[col][row]['state'] == CELL_TURNING_ON then
                if CELLS[col][row]['frame'] < 11 then
                        CELLS[col][row]['frame'] = CELLS[col][row]['frame'] + 1
                else
                        CELLS[col][row]['state'] = CELL_ON
                end
        elseif CELLS[col][row]['state'] == CELL_TURNING_OFF then
                if CELLS[col][row]['frame'] > 0 then
                        CELLS[col][row]['frame'] = CELLS[col][row]['frame'] - 1
                else
                        CELLS[col][row]['state'] = CELL_OFF
                end
        end
        
        return (CELLS[col][row]['state'] == CELL_OFF)
end -- DrawCell




function game_onstylusdown(x,y)
        -- ignore clicks if we're animating for level completion
        if AUTOTURNER_BAR ~= 0 then
                return
        end
        
        -- detect on which cell we clicked (if any)
        local cx = math.floor((x -5) / 23)
        local cy = math.floor((y -18) / 23)

        -- perfect check on circle
	local centerX = x - ((5 + cx *23)+11);
	local centerY = y - ((18 + cy *23)+11);

        if (cx >= 0 and cx < 10 and cy >= 0 and cy < 10 and (centerX*centerX+centerY*centerY <= 144) ) then
        
              -- accept clicks only on cells that aren't animating
              -- mouse is on the ball, flag as clicked
              if cellIsClickable(cx, cy, false) then
                      if CELLS[cx][cy]['state'] == CELL_OFF then
                            CELLS[cx][cy]['state'] = CELL_OFF_CLICK
                      elseif CELLS[cx][cy]['state'] == CELL_ON then
                            CELLS[cx][cy]['state'] = CELL_ON_CLICK
                      end
                     
                     -- and play click sound
                     playsound(SNDCLICK)
              end
                            
              
         end
         
         -- check click on left/right arrow
         if mousein(30, 254, 42, 265) then
                LEFT_ARROW_CLICK = 1

                if LOADED_LEVEL > 1 then 
                        playsound(SNDLEVELCLICK)
                        LOADED_LEVEL = LOADED_LEVEL - 1
                        LoadLevel(LOADED_LEVEL)
                else
                        playsound(SNDCANTCLICK)
                end


         elseif mousein(45, 254, 57, 265) then
                RIGHT_ARROW_CLICK = 1
                
                if LOADED_LEVEL < 50 and LOADED_LEVEL < MAX_UNLOCKED_LEVEL then
                        playsound(SNDLEVELCLICK)
                        LOADED_LEVEL = LOADED_LEVEL + 1
                        LoadLevel(LOADED_LEVEL)
                else
                        playsound(SNDCANTCLICK)
                end


         elseif mousein(188, 273, 188+40, 273+imageheight(IMGHOMEBUTTON)) then
                -- home button
                HOME_CLICKED = 1
                playsound(SNDHEAVYCLICK)
         end
        
end -- onstylusdown


function game_onstylusup(x,y)
        -- ignore clicks if we're animating for level completion
        if AUTOTURNER_BAR ~= 0 then
                return
        end

        -- detect from which cell we released the mouse (if any)
        local cx = math.floor((x -5) / 23)
        local cy = math.floor((y -18) / 23)

        -- perfect check on circle
	local centerX = x - ((5 + cx *23)+11);
	local centerY = y - ((18 + cy *23)+11);
        local triggered = false
        
        if (cx >= 0 and cx < 10 and cy >= 0 and cy < 10 and (centerX*centerX+centerY*centerY <= 144) ) then
                
                -- released on a clicked cell, trigger the click!
                if cellIsClickable(cx, cy, true) then
                        if CELLS[cx][cy]['state'] == CELL_ON_CLICK or CELLS[cx][cy]['state'] == CELL_OFF_CLICK then
                                
                                if CELLS[cx][cy]['state'] == CELL_ON_CLICK then
                                        CELLS[cx][cy]['state']=CELL_ON
                                else
                                        CELLS[cx][cy]['state']=CELL_OFF
                                end
                                
                                MAX_MOVES = MAX_MOVES - 1
                                TOTAL_MOVES = TOTAL_MOVES + 1
                                      
                                numret = crossInvertCell(cx, cy)     
                                
                                -- play swish sound
                                playsound(SNDSWISH)
                                
                                -- play blip if we turned off 5 cells
                                if numret == 5 then playsound(SNDBLIP) end

                                
                                triggered = true                  
                        end
                end
        end
        
        -- not released on the cell, now unclick all clicked cells
        if triggered == false then
                for x=0, COLS-1 do
                        for y=0, ROWS-1 do
                                if CELLS[x][y]['state'] == CELL_OFF_CLICK then
                                        CELLS[x][y]['state'] = CELL_OFF
                                elseif CELLS[x][y]['state'] == CELL_ON_CLICK then
                                        CELLS[x][y]['state'] = CELL_ON
                                end
                        end
                end
        end
        
        -- release level arrows
        LEFT_ARROW_CLICK = 0
        RIGHT_ARROW_CLICK = 0
        
        -- clicked on home button
        if mousein(188, 273, 188+40, 273+imageheight(IMGHOMEBUTTON)) then
                -- back to menu
                HOME_CLICKED = 0
                CURRENT_STATE = STATE_MENU
        end
        
end -- onstylusup


function DoStars()        

	-- draw rank stars
	if MAX_UNLOCKED_LEVEL >= 8  then drawimage(IMGSTARS,85,301) end
	if MAX_UNLOCKED_LEVEL >= 16 then drawimage(IMGSTARS,101,301) end
	if MAX_UNLOCKED_LEVEL >= 24 then drawimage(IMGSTARS,118,301) end
	if MAX_UNLOCKED_LEVEL >= 32 then drawimage(IMGSTARS,135,301) end
	if MAX_UNLOCKED_LEVEL >= 40 then drawimage(IMGSTARS,152,301) end
	if MAX_UNLOCKED_LEVEL >= 50 then drawimage(IMGSTARS,169,301) end
	
end -- DoStars


function LoadLevel(level)
        
        MAX_MOVES = string.sub( LEVELS[level], 1, 3)
        LOADED_LEVEL = level
        
        local pos = 3
        
        for x=0, COLS-1 do
                for y=0, ROWS-1 do
                        
                        pos = pos + 1
                                        
                        local car = string.sub( LEVELS[level], pos, pos)
                        
                        if car == "1" then
                                TurnOnCell(x, y)
                        end               
                        if car == "0" then
                                TurnOffCell(x, y)
                        end
                end
        end
        
        -- according to current level, set max available moves
        local toadd = 50-(math.floor(level / 10)*10)
        if toadd < 0 then toadd = 0 end
        MAX_MOVES=MAX_MOVES+toadd
	
end -- LoadLevel(level)


function TurnOnCell(x,y)
        CELLS[x][y]['frame'] = 0
        CELLS[x][y]['state'] = CELL_TURNING_ON
end -- turnOnCell

function TurnOffCell(x,y)
        CELLS[x][y]['frame'] = 11
        CELLS[x][y]['state'] = CELL_TURNING_OFF
end -- turnOnCell


-- click on a cell and invert status of adjacent cells
-- returns number of turned off cells
function crossInvertCell(x, y)
        local ret = 0
        
        -- invert selected cell
        if CELLS[x][y]['state'] == CELL_OFF then
                TurnOnCell(x, y)
        elseif CELLS[x][y]['state'] == CELL_ON then 
                TurnOffCell(x, y)
                ret = ret + 1
        end
        

	-- try left cell
	if x > 0 then
                if CELLS[x-1][y]['state'] == CELL_OFF then
                        TurnOnCell(x-1, y)
                elseif CELLS[x-1][y]['state'] == CELL_ON then 
                        TurnOffCell(x-1, y)
                        ret = ret + 1
                end
	end
	
	-- try up cell
	if y > 0 then
                if CELLS[x][y-1]['state'] == CELL_OFF then
                        TurnOnCell(x, y-1)
                elseif CELLS[x][y-1]['state'] == CELL_ON then 
                        TurnOffCell(x, y-1)
                        ret = ret + 1
                end
	end
	
	-- try right cell
	if x < COLS-1 then
                if CELLS[x+1][y]['state'] == CELL_OFF then
                        TurnOnCell(x+1, y)
                elseif CELLS[x+1][y]['state'] == CELL_ON then 
                        TurnOffCell(x+1, y)
                        ret = ret + 1
                end
	end
	
	-- try down cell
	if y < ROWS-1 then
                if CELLS[x][y+1]['state'] == CELL_OFF then
                        TurnOnCell(x, y+1)
                elseif CELLS[x][y+1]['state'] == CELL_ON then 
                        TurnOffCell(x, y+1)
                        ret = ret + 1
                end
	end
	
	return ret	-- return number of cells we turned off
end


-- tell us if a cell is clickable or not
-- a cell is clickable if:
-- it isn't animating
-- all adjacent cells are not animating
--
function cellIsClickable(x, y, esclude_itself)
        if esclude_itself == false and CELLS[x][y]['state'] ~= CELL_OFF and CELLS[x][y]['state'] ~= CELL_ON then return false
        elseif x > 0 and CELLS[x-1][y]['state'] ~= CELL_OFF and CELLS[x-1][y]['state'] ~= CELL_ON then return false
        elseif x < COLS-1 and CELLS[x+1][y]['state'] ~= CELL_OFF and CELLS[x+1][y]['state'] ~= CELL_ON then return false
        elseif y > 0 and CELLS[x][y-1]['state'] ~= CELL_OFF and CELLS[x][y-1]['state'] ~= CELL_ON then return false
        elseif y < ROWS-1 and CELLS[x][y+1]['state'] ~= CELL_OFF and CELLS[x][y+1]['state'] ~= CELL_ON then return false end
        return true
end -- cellIsClickable
