
jit.on()
local csm = require('csm')
local core = require('core')
local graphics = require('graphics')
local draw = require('draw')
local Image = require('image')
local clock = require('clock')
local timer = require('timer')
local dir = require('dir')
local ttf = require('ttf')
local ffi = require('ffi')


local _ucf = ""
local mycsm
local _m_menu = "Menu"
local _m_exit = "Exit"
local curent_folder = "\\"

local background = Image(sys.pDir().."background.png")
local checked_pic = Image((sys.pDir()).."icons\\CHECKED.PNG")
local ifolder = Image((sys.pDir()).."icons\\FOLDER.PNG")
local iunk = Image((sys.pDir()).."icons\\UNKNOWN.PNG")
local icursor = Image((sys.pDir()).."icons\\cursor.png")

local names_array = {{}}
local select_list = {}
local selected_num = 0

local mem_last_cursor_pos = {}
local mem_last_shift = {}
local navigation_counts = 0

local elements = 0
local font = graphics.FONT_SMALL
local fontY = draw.getFontH(font)
local ftfont12
local ftfont13
local StringArray = ffi.cast('char **', ffi.new('char[256]'))

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

local br_ln = 4
local display_strs = round( (graphics.height()-45)/(fontY+br_ln) )
local curent_ds = display_strs
local cursor_pos = 0
local file_seek = 0
local scr_W = graphics.width()
local scr_H = graphics.height()

local fps = 0
local fps_count = 0
local cur_time = 0


collectgarbage('setpause', 100000)

local isMenuDrawing = false

print("display strs: "..display_strs)
-- ======================

menubarpos = {round((scr_H-fontY)-2), round(scr_W/2)}

ftfont12 = ttf.open('tahoma.ttf', 12)
ftfont13 = ttf.open('tahoma.ttf', 13)

local function get_namesarray(folder, mask)
  
  array = {}
  tarray = {}
  iterator = 0
  
  diri, ret = dir.findFirstFile(folder..mask) 
  if ret == nil or diri == nil then
    return -1, -1, -1, -1
  end

  while ret ~= 0 do  
    array[iterator] = ((diri:name()))     
    
    if(bit.band(diri:attr(),  0x0010))   ~= 0    then    
      array[iterator] = array[iterator].."\\"
      tarray[iterator] = ifolder
    else
      tarray[iterator] = iunk
    end

    select_list[iterator] = false
    
  ret =(diri:findNextFile())
  iterator = iterator+1
  end
  
  selected_num = 0
  iterator = iterator-1
  
  diri:findClose()
  diri = nil
  return array, tarray, iterator
end

 -- запоминание положения курсора
local function _mempos_push(pos, shift)
  mem_last_cursor_pos[navigation_counts] = pos
  mem_last_shift[navigation_counts] = shift
  navigation_counts = navigation_counts + 1
end

 -- восстановление положения куросра
local function _mempos_pop()
  if navigation_counts < 0 then
    print "bad pop index"
    return nil, nil
  end
  navigation_counts = navigation_counts - 1
  return mem_last_cursor_pos[navigation_counts], mem_last_shift[navigation_counts]
  
end


local function flush_toDisk()
  
  array = {}
  tarray = {}
  
  array[0] = "0:\\"
  array[1] = "1:\\"
  array[2] = "2:\\"
  array[3] = "4:\\"
  
  tarray[0] = ifolder
  tarray[1] = tarray[0]
  tarray[2] = tarray[0]
  tarray[3] = tarray[0]
  
  local arrsz = #array+1
  StringArray = ffi.cast('char **', ffi.new(string.format('char[%d]', (arrsz+4) * 4)) )
  print('Array sz: '..arrsz)
  local i = 0;
  while(i < arrsz) do
    StringArray[i] = ffi.cast('char *', array[i])
    i = i+1
  end
  
  iterator = 3
  return array, tarray, iterator
end


function enter_to()
  
  if cursor_pos == nil then
    --curent_folder = curent_folder..(string.sub(array[cursor_pos+file_seek], 2))
    return
  end
  
  if curent_folder:at(1) == '\\' then
    s = array[cursor_pos+file_seek]
  else
    s = curent_folder..( array[cursor_pos+file_seek])
  end
  
  if s:at(s:len()) ~= '\\' then
    print ("exec file: '"..s.."'")
    sys.exec(s, 0)
    return 
  end
  
  print("Enter to: '"..s.."'")
  names, ntypes, el = 0, 0, 0
  
  _mempos_push(cursor_pos, file_seek)
  
  names, ntypes, el = get_namesarray(s, "*.*")
  
  if el == -1 then
    cursor_pos = nil
    elements = 0
    file_seek = 0
    curent_folder = s
    --FIXME
    --_ucf = ustring.from_sieUnicode(curent_folder)
    _ucf = curent_folder
    
    print("Empty")
    return 0
  end
  
  curent_ds = display_strs
  
  if curent_ds > el then
    curent_ds = el
  end
  
  file_seek= 0
  cursor_pos = 0
  curent_folder = s
  
  --FIXME
  --_ucf = ustring.from_sieUnicode(curent_folder)
  _ucf = curent_folder
  
  local arrsz = #names+1
  StringArray = ffi.cast('char **', ffi.new(string.format('char[%d]', (arrsz+4) * 4)) )
  print('Array sz: '..arrsz)
  local i = 0;
  while(i < arrsz) do
    StringArray[i] = ffi.cast('char *', names[i])
    i = i+1
  end
  
  names_array[0], names_array[1], elements = names, ntypes, el
end


local function string_UP(folder)
  
  rev = folder:reverse()
  if rev:at(2) == ':' or folder:at(1) == '\\' then
    return nil
  end
  
  folder = folder:sub(1, ( rev:len() - (rev:find("\\", 2)-1) ) )
  return folder
end


local function go_Up()
  
  if(curent_folder == '\\') then
    return
  end
  cursor_pos = 0
  s = string_UP(curent_folder)
  
  names, ntypes, el = 0, 0, 0
  
  if s == nil then
    s = "\\"
    names, ntypes, el = flush_toDisk()
  else
    print("Up to: '"..s.."'")
    names, ntypes, el = get_namesarray(s, "*.*")
  end
  
  if el == -1 then
    cursor_pos = nil
    print("Up Empty оО")
    --ui.emsg(1, "Cant open directory")
    return 0
  end
  
  file_seek = 0
  curent_ds = display_strs
  
  if curent_ds > el then
    curent_ds = el
  end
  
  cursor_pos = 0
  curent_folder = s
  
  --FIXME
  --_ucf = ustring.from_sieUnicode(curent_folder)
  _ucf = curent_folder
  
  local arrsz = #names+1
  StringArray = ffi.cast('char **', ffi.new(string.format('char[%d]', (arrsz+4) * 4)) )
  print('Array sz: '..arrsz)
  local i = 0;
  while(i < arrsz) do
    StringArray[i] = ffi.cast('char *', names[i])
    i = i+1
  end
  
  names_array[0], names_array[1], elements = names, ntypes, el
  
  --if s ~= '\\' then
    cursor_pos, file_seek = _mempos_pop()
  --end
end



local tm = br_ln/2
local tm2 = br_ln/2*2

local black = draw.getColor(0,0,0,100)
local white = draw.getColor(0xff,0xff,0xff,100)
local red = draw.getColor(0xff,0,0,100)
local green = draw.getColor(0,0xff,0,100)
local blue = draw.getColor(0,0,0xff,100)
local empty_color = draw.getColor(0, 0, 0, 0)
local yellow = draw.getColor(255,255,0,100)
local agrey = draw.getColor(50, 50, 50, 60)
local dstr = ""
local canv = draw.buildCanvas()
local fpsinfo = "FPS: 0"


local function _draw()
  draw.directRedrawGUI()
end



local function onRedraw()
  
  
  --draw.drawCanvas(canv, 0, 0, scr_W, scr_H, 1)
  background:draw(0, 0)


  draw.drawRoundedFrame(0, 0, scr_W-1, 15, 0, 0, 0, black, agrey)
  

  if cursor_pos == nil then
    dstr = "0/0"
    draw.drawString(dstr, 30,
        0, 2, scr_W-2, scr_H, font, 37, yellow, empty_color)
  else
    dstr = (cursor_pos+file_seek+1).."/"..elements+1
    draw.drawString(dstr, 30,
        0, 2, scr_W-2, scr_H, font, 37, yellow, empty_color)
  end

  draw.drawScrollString(--[[_ucf--]] fpsinfo, 30, 2, 2, scr_W-27, 20, 1, font, 37, yellow, empty_color)
  

  draw.drawScrollString(_m_menu, 30, 3, menubarpos[1], 
    menubarpos[2], scr_H, 1, font, 37, yellow, empty_color)


  draw.drawString(_m_exit, 30, 0, scr_H-fontY-2, scr_W-3, scr_H, font, 37, yellow, empty_color)
  
  
  if cursor_pos == nil then
    draw.drawString("<Empty>", 7, 0, 25, scr_W-1, 176, font, 34, yellow, empty_color)
    return 
  end

  local pos = (fontY*cursor_pos+cursor_pos*2)
  local sk = 0
  local i = 0;
  
  icursor:draw(18, 17+(tm)+ (pos))
                           -- 1+16
  --draw.drawRoundedFrame(18, 17+(tm)+ (pos),
  --  129, 16+(tm2)+ (pos) +fontY, 0, 0, 0, black, agrey)
  
  
  local fordisp = display_strs+1
  if( #names_array[0] < display_strs ) then
    fordisp = #names_array[0]+1
  end
  
  -- this is mega hask for drawing strings array :-D
  draw.drawStringArray(StringArray+file_seek, fordisp, 20, 20, 126, 176, 2, 11, 32, yellow, empty_color)
  
  i = 0

  while i <= curent_ds do

    if select_list[i+file_seek] == false then
      names_array[1][i+file_seek]:draw(2, 17+(tm)+(fontY*i+i*2))
    else
      checked_pic:draw(2, 17+(tm)+(fontY*i+i*2))
    end


    --core.drawStr(20, 16+4+sk, 126, 16+4+sk+fontY+1)
    --draw.drawScrollString(names_array[0][i+file_seek],
	--  30, 20, 16+4+sk, 126, 16+4+sk+fontY+1, 
	  --1, font, 37, yellow, empty_color)
      
      --ttf.drawstring(ftfont12, names_array[0][i+file_seek],
	--  20, 17+4+sk, 126, 17+4+sk+fontY+1, 8, 0, 128, 0xFFFFFF00)

    i = i+1
    --sk = sk+(fontY+tm)
  end

  
  if isMenuDrawing == true then
    drawMenu()
    return 
  end
  
  if cur_time ~= (clock.time().sec)  then
    fps = fps_count
    fpsinfo = 'FPS '..fps;
    fps_count = 0
    cur_time = clock.time().sec
  end
  
  fps_count = fps_count+1
  --timer_id = timer.start(_draw, 1)
  
end


local function onCreate()
  
  if curent_folder == '\\' then
    names_array[0], names_array[1], elements = flush_toDisk()
  else
    names_array[0], names_array[1], elements = get_namesarray(curent_folder, "*.*")
  end
  
  i = 0
  while i <= elements do
    select_list[i] = false
    i = i+1
  end
  
  if elements == -1 then
    ui.emsg(1, "Cant open directory")
  end
  
  if curent_ds > elements then
    curent_ds = elements
  end
  
end


local function onKey(type, code)

  if isMenuDrawing == true then
    return (keyMenu(type, code))
  end

  if type == 403 or type == 405 then

    if code == 4 then
      --sys.exit()
      return 1
    elseif code == 1 then
      isMenuDrawing = true

    elseif code == 59 then
      if cursor_pos ~= nil then cursor_pos = cursor_pos-1 end

    elseif code == 60 then
      if cursor_pos ~= nil then cursor_pos = cursor_pos+1 end

    elseif code == 61 then
      go_Up()
      draw.directRedrawGUI()
      return 0
      
    elseif code == 26 then
      enter_to()
      draw.directRedrawGUI()
      return 0
      
    elseif code == 11 then
      if select_list[cursor_pos+file_seek] == false then
	select_list[cursor_pos+file_seek] = true
	selected_num = selected_num+1
      else
	select_list[cursor_pos+file_seek] = false
	selected_num = selected_num-1
      end
      cursor_pos = cursor_pos +1
    end
  end
  
  if cursor_pos ~= nil then
    
    if cursor_pos < 0 then
      if file_seek > 0 then
	file_seek = file_seek-1
	cursor_pos = 0
      else
	cursor_pos = curent_ds
	file_seek = elements-curent_ds
      end
    
    elseif cursor_pos > curent_ds then
      file_seek = file_seek+1
      cursor_pos = curent_ds
    end
  
    if file_seek > elements-curent_ds then
      file_seek = 0
      cursor_pos = 0
    end
  end
  
  draw.directRedrawGUI()
  return 0
end


 -- [[  ================= Меню ====================  ]]
function setMenuDrawing(is)
  isMenuDrawing = is
end

function __onredraw()
  onRedraw()
end

function setFileUnChecked(index)
  select_list[index] = false
end

function chekedFileList()
  if(selected_num == 0) then
    return cursor_pos+file_seek, 1, true
  end
  return select_list, elements, false
end

function curentFolder()
  return curent_folder
end

function nameByIndex(index)
  return names_array[0][index]
end


dofile(sys.pDir().."fmMenu.lua")
_menu_export(font, fontY)



-- ============== csm ===============

local function __on_all()
end

function csm_onCreate(csm_data)
  
  gui_id = graphics.new(onRedraw,
		    onCreate,
		    __on_all, -- onClose
		    __on_all, -- onFocus
		    __on_all, -- onUnfocus
		    onKey)

  csm.parentOfGui(csm_data, gui_id:id());
end


function onExit(csm_data)
  ftfont12 = nil
  ftfont13 = nil
  gui_id = nil
  mycsm = nil
  sys.exit();
end

function onMessage(csm_data, msg)
  return 1
end


mycsm = csm.new(1, "Free FM", csm_onCreate, onExit, onMessage)

