--[[
=============================================
vexed.lua by Cancan

Game functions for Vexed

Email: cancangm (at) gmail (dot) com
=============================================
]]

function SaveScore()
  file = io.open(cwd .. "/levels/" .. levelpacks.name .. ".score", "w")
  if file then
    for idx = 1, levelmax do
      file:write(levelscores[idx] .. "\n")
    end
    file:close()
  end
end

function RenderTiles()

  screen:blit(0, 0, background, 0, 0, background:width(), background:height(), false)
  screen:blit(20, 36, boardback)
  screen:blit(20, 36, boardtiles)

  if ifselected then
    screen:blit(20 + ((posx - 1) * 25), 36 + ((posy - 1) * 25), tiles, 250, 0, 25, 25, true)
  else
    screen:blit(20 + ((posx - 1) * 25), 36 + ((posy - 1) * 25), tiles, 225, 0, 25, 25, true)
  end

  screen:print(312, 65, levelpacks.name, labelcolor)
  screen:print(360, 85, levelcurr .. " / " .. levelmax, labelcolor)
  screen:print(312, 100, leveltitles[levelcurr], labelcolor)
  screen:print(372, 115, levelsol[levelcurr], labelcolor)
  screen:print(372, 130, levelscores[levelcurr], labelcolor)
  screen:print(372, 145, levelsteps, labelcolor)

end

function RenderLevel()
  local line = 0
  local column = 0
  local levelpos = 0

  boardtiles:clear()
  boardback:clear()

  levelremaining = 0
  for line = 1,  8 do
    for column = 1, 10 do
      levelpos = ((line - 1) * 10) + column
      if currlevel[levelpos] ~= 9 then
        if currlevel[levelpos] ~= 8 then
          levelremaining = levelremaining + 1
          boardtiles:blit((column - 1) * 25, (line - 1) * 25, tiles, currlevel[levelpos] * 25, 0, 25, 25, true)
        else
          boardback:blit((column - 1) * 25, (line - 1) * 25, tiles, 200, 0, 25, 25, true)
        end
      end
    end
  end

  RenderTiles()

end
  

function TileFall(gposx, gposy)

  newposy = gposy

  gloop =  true
  while gloop do
    newposy = newposy - 1
    if currlevel[((newposy - 1) * 10) + gposx] > 7 then
      currlevel[(newposy * 10) + gposx] = 9
      boardtiles:fillRect((gposx - 1) * 25, newposy * 25,  25, 25)
      if currlevel[((newposy - 1) * 10) + gposx] == 8 then
        gloop = flase
      end
    else
      currlevel[(newposy * 10) + gposx] = currlevel[((newposy - 1) * 10) + gposx]
      boardtiles:blit((gposx - 1) * 25, newposy * 25, tiles, currlevel[(newposy * 10) + gposx] * 25 , 0, 25, 25, true)
    end
    if newposy == 1 then
      gloop = false
    end
  end
  if newposy == 1 then
    if currlevel[10 + gposx] ~= 8 then
      currlevel[10 + gposx] = 9
    end
    boardtiles:fillRect((gposx - 1) * 25, 0,  25, 25)
  end

end

function TileMove(newmove)
            
  if currlevel[((posy - 1) * 10) + (posx + newmove)] == 9 then
    levelsteps = levelsteps + 1
    levelundo[levelsteps] = {}
    for idx = 1, 80 do
      levelundo[levelsteps][idx] = currlevel[idx]
    end
    undoposx[levelsteps] = posx
    undoposy[levelsteps] = posy

    TileFall(posx, posy)
    
    posx = posx + newmove
    boardtiles:blit((posx - 1) * 25, (posy - 1) * 25, tiles, selectvalue * 25, 0, 25, 25, true)
    currlevel[((posy - 1) * 10) + posx] = selectvalue

    selectx = posx
    selecty = posy
    if currlevel[((selecty - 1) * 10) + selectx] == selectvalue then
      ifselected = true
    end

    AnalyseMap()
  else
    if vexedsound == 1 then
      vexedsndno:play()
    end
  end

end

function TileFalls()

  flevelpos = ((posy - 1) * 10) + posx
  newvalue = currlevel[flevelpos]
    
  if currlevel[flevelpos] < 8 then
    if currlevel[flevelpos + 10] == 9  then
      TileFall(posx, posy)
      posy = posy + 1
      selecty = posy
      boardtiles:blit((posx - 1) * 25, (posy - 1) * 25, tiles, newvalue * 25, 0, 25, 25, true)
      currlevel[((posy - 1) * 10) + posx] = newvalue 
      if posy < 8 and currlevel[(posy * 10) + posx] == 9 then
        toanalyse = 1
      end
    end
  end

end

function AnalyseMap()

  toanalyse = 0

  TileFalls()

  line = 8
  
  if toanalyse == 0 then
    while line > 0 do
      column = 10
      while column > 1 do
        levelpos = ((line - 1) * 10) + column
        if currlevel[levelpos] < 8 then
          levelpos = ((line - 1) * 10) + column
          if currlevel[levelpos] == currlevel[levelpos - 1] then
            if column > 2 and currlevel[levelpos] == currlevel[levelpos - 2] then
              TileFall(column - 2, line)
              levelremaining = levelremaining - 1
            end
            TileFall(column - 1, line )
            TileFall(column, line)
            levelremaining = levelremaining - 2
            line = 0
            column = 1
            ifselected = false
            toanalyse = 1
          else
            if line > 1 and currlevel[levelpos - 10] == currlevel[levelpos] then
              if currlevel[levelpos - 11] == currlevel[levelpos] then
                TileFall(column - 1, line - 1)
                levelremaining = levelremaining - 1
              end
              if column < 10 and currlevel[levelpos - 9] == currlevel[levelpos] then
                TileFall(column + 1, line - 1)
                levelremaining = levelremaining - 1
              end
              TileFall(column, line - 1)
              TileFall(column, line)
              levelremaining = levelremaining - 2
              line = 0
              column = 1
              ifselected = false
              toanalyse = 1
            end
          end
        end
        column = column - 1
      end
      line = line - 1
    end

    if toanalyse == 0 then
      if levelremaining == 0 then
        if levelscores[levelcurr] == 0 or levelscores[levelcurr] > levelsteps then
          levelscores[levelcurr] = levelsteps
        end
        SaveScore()
        if levelcurr < levelmax then
          levelcurr = levelcurr + 1
          if levelcurr == leveltop + levellines then
            leveltop = levelcurr
          end
          if vexedsound == 1 then
            vexedsndyes:play()
          end
          InitLevel()
        else
          if vexedsound == 1 then
            vexedsnddone:play()
          end
        end
        SaveSettings()
      end
    end
  end

end

function InitLevel()
  currlevel = {}
  levelundo = {}
  levelundo[1] = {}

  local line = 0
  local column = 0
  local levelpos = 0

  for line = 1, 8 do
    for column = 1, 10 do
      levelpos = ((line - 1) * 10) + column
      currlevel[levelpos] = string.sub(levels[levelcurr], levelpos, levelpos)
    end
  end

  for line = 1, 8 do
    for column = 1, 10 do
      levelpos = ((line - 1) * 10) + column
      if currlevel[levelpos] ~= "A" and currlevel[levelpos] ~= "8" then
        if line == 8 then
          if currlevel[levelpos - 10] == "A"  then currlevel[levelpos - 10] = "8" end
          if column == 10 then
            if currlevel[levelpos - 1] == "A"  then currlevel[levelpos - 1] = "8" end
          else
            if currlevel[levelpos + 1] == "A"  then currlevel[levelpos + 1] = "8" end
            if column ~= 1 then
              if currlevel[levelpos - 1] == "A"  then currlevel[levelpos - 1] = "8" end
            end
          end
        else
          if line ~= 1 then
            if currlevel[levelpos - 10] == "A"  then currlevel[levelpos - 10] = "8" end
          end
          if currlevel[levelpos + 10] == "A"  then currlevel[levelpos + 10] = "8" end
          if column == 10 then
            if currlevel[levelpos - 1] == "A"  then currlevel[levelpos - 1] = "8" end
          else
            if currlevel[levelpos + 1] == "A"  then currlevel[levelpos + 1] = "8" end
            if column ~= 1 then
              if currlevel[levelpos - 1] == "A"  then currlevel[levelpos - 1] = "8" end
            end
          end
        end
      end
    end
  end

  for line = 1, 8 do
    for column = 1, 10 do
      levelpos = ((line - 1) * 10) + column
      if currlevel[levelpos] == "A" then currlevel[levelpos] = "9" end
      currlevel[levelpos] = tonumber(currlevel[levelpos])
      levelundo[1][levelpos] = currlevel[levelpos]
    end
  end

--[[  for line = 1, 8 do
    for column = 1, 10 do
      levelpos = ((line - 1) * 10) + column
      currlevel[levelpos] = string.sub(levels[levelcurr], levelpos, levelpos)
      if currlevel[levelpos] == "A" then currlevel[levelpos] = "9" end
      currlevel[levelpos] = tonumber(currlevel[levelpos])
      levelundo[1][levelpos] = currlevel[levelpos]
    end
  end
]]

  leveltitle = leveltitles[levelcurr]
  posx = 5
  posy = 5
  undoposx[1] = 5
  undoposy[1] = 5
  ifselected = false
  levelsteps = 0
  RenderLevel()
end

function LoadLevelPack(newlevel)
  levelmax = 0
  levels = {}
  leveltitles = {}
  levelscores = {}
  levelcurr = newlevel
  leveltop = 1
  levelsol = {}

  file = io.open(cwd .. "/levels/" .. levelpacks.name .. ".ini", "r")
  if file then
    for line in file:lines() do
      eofchar = string.find(line, "\r")
      if eofchar then
       line = string.sub(line, 1, eofchar - 1)
      end
      index = string.find(line, "=")
      if index then
        key = string.sub(line, 1, index - 1)
        value = string.sub(line, index + 1)
        if key == "board" then
          levelmax = levelmax + 1
          line = string.gsub(value, "10", "AAAAAAAAAA")
          line = string.gsub(line, "9", "AAAAAAAAA")
          line = string.gsub(line, "8", "AAAAAAAA")
          line = string.gsub(line, "7", "AAAAAAA")
          line = string.gsub(line, "6", "AAAAAA")
          line = string.gsub(line, "5", "AAAAA")
          line = string.gsub(line, "4", "AAAA")
          line = string.gsub(line, "3", "AAA")
          line = string.gsub(line, "2", "AA")
          line = string.gsub(line, "1", "A")
          line = string.gsub(line, "~", "9")
          line = string.gsub(line, "a", "0")
          line = string.gsub(line, "b", "1")
          line = string.gsub(line, "c", "2")
          line = string.gsub(line, "d", "3")
          line = string.gsub(line, "e", "4")
          line = string.gsub(line, "f", "5")
          line = string.gsub(line, "g", "6")
          line = string.gsub(line, "h", "7")
          line = string.gsub(line, "/", "")
          levels[levelmax] = line
          levelscores[levelmax] = 0
        end   
        if key == "title" then
          leveltitles[levelmax] = value
        end
        if key == "solution" then
          levelsol[levelmax] = string.len(value) / 2
        end
      end
    end
    file:close()
    idx = 0
    file = io.open(cwd .. "/levels/" .. levelpacks.name .. ".score", "r")
    if file then
      for line in file:lines() do
        eofchar = string.find(line, "\r")
        if eofchar then
         line = string.sub(line, 1, eofchar - 1)
        end
        idx = idx + 1
        leveltop = tonumber(line)
        levelscores[idx] = leveltop
        if leveltop == 0 and levelcurr == 0 then
          levelcurr = idx
        end
      end
      file:close()
    end
  end
  leveltop = 1
  if levelcurr == 0 then
    levelcurr = 1
  end
end
