local VALUE = 0
local COMBO = 1

local TA_LEFT = 0
local TA_RIGHT = 1

local fields = {}

local printText = (0x800 + 0x02)
local hPWin = 0
local Id = 0
local editMode = false
local modifications = {}
local refreshState = 0
local calibrationStep = 0
local calibrationState = 0
local pageOffset = 0
local page = 1
local pages = {}

local appId = 0
local newAppId = 0

local settingsFields = {
  {"SBEC OUTPUT VOLTAGE(V)", VALUE, 0x80, nil, 50, 84 , 1},
  {"Physical ID", VALUE, 0x01, nil, 0, 26,0 },
  {"Application IDgroup", VALUE, 0x0D, nil, 0, 15,0 },
  {"Data rate(*100ms)", VALUE, 0x22, nil, 1, 255,0 },
}

local function telemetryRead(fieldx)
  return sport.TelemetryPush(0x08, 0x30, appId, fieldx)
end

local function telemetryIdle(field)
    return sport.TelemetryPush(0x08,0x21,appId,field)
end

local function telemetryUnIdle(field)
    return sport.TelemetryPush(0x08,0x20,appId,field)
end

local function telemetryWrite(fieldx, valuex)
  return sport.TelemetryPush(0x08, 0x31, appId, fieldx + valuex*256)
end

-- Redraw the current page
local function redrawFieldsPage(hWin)
  
  if #fields > NUM_PER_PAGE then
    drawScrollbar(hWin, #fields, NUM_PER_PAGE, pageOffset)
  end

	for index = 1, NUM_PER_PAGE, 1 do
		local field = fields[pageOffset+index]
		if field == nil then
		  break
		end		
    
    drawText(hWin, index-1, field[1], TA_LEFT)
    
		if field[4] == nil then
			if field[2] == VALUE then
				drawEdit(hWin, index-1, "---")
			elseif field[2] == COMBO then			
				drawDropdown(hWin, index-1, 0, "---")
			end	
		else
      if field[2] == VALUE then        
        drawEdit(hWin, index-1, field[4], field[5], field[6], field[7])
      elseif field[2] == COMBO then
        if field[4] >= 0 and field[4] < #(field[5]) then		
          local attr = field[5][1].."|"
          for index2 = 2,  #(field[5]), 1 do
            attr = attr..field[5][index2]
            if index2 <= #(field[5]) then
              attr = attr.."|"
            end
          end		
        drawDropdown(hWin, index-1, field[4], attr)
        end
      end
    end
  end
end

local function refreshNext() 
  if refreshState == 0 then 
    if #modifications > 0 then 
      local modificationstmp = modifications[1][2]		
      telemetryWrite(modifications[1][1], modificationstmp)
      refreshIndex = 0
      modifications[1] = nil
    elseif refreshIndex < #fields then
      local field = fields[refreshIndex + 1]
      if appId ~= newAppId and 0~=newAppId then
        appId = newAppId
      end
      if telemetryRead(field[3]) == true then
        refreshState = 1
        telemetryPopTimeout = getTime() + 200
      end
    end    
  elseif refreshState == 1 then
    local appId, primId, value = sport.TelemetryPop()  
    if primId == 0x32 and appId >= 0x0e50 and appId <= 0x0e5f then          
      local fieldId = value % 256
      local field = fields[refreshIndex + 1]
      if fieldId == field[3] then
        local value = math.floor(value / 256)
        if field[2] == VALUE  then
          value = value
        end
		
        fields[refreshIndex + 1][4] = value
        refreshIndex = refreshIndex + 1
        refreshState = 0
      end
    elseif getTime() > telemetryPopTimeout then
      refreshState = 0
    end 
  end
end

-- Main
local function runFieldsPage(hWin, Key)  
  redrawFieldsPage(hWin)
  return 0
end


local function runSettingsPage(hWin, Key)

  fields = settingsFields    
  
  local result
  
  if false == editMode then
    result = runFieldsPage(hWin, Key) 
  end
  
  return result
end

-- Select the next or previous page
local function selectPage(step)
  page = 1 + ((page + step - 1 + #pages) % #pages)
  
	current, edit, refreshState, refreshIndex, pageOffset, calibrationStep, calibrationState = 1, false, 0, 0, 0, 0, 0
      
  clearAll(hPWin)  
end

-- Select the next or previous editable field
local function selectField(step)
  local retValue = 1
  current = current + step  
  
  if current > #fields then
    current = #fields 
  elseif current < 1 then  
    current = 1
  elseif current > NUM_PER_PAGE + pageOffset then
    pageOffset = current - NUM_PER_PAGE
  elseif current <= pageOffset then
    pageOffset = current - 1 
  else
    retValue = 0
  end
  
  return retValue
end


local function updateField(field)
  local value = field[4]
  if nil ~= value then
    value = getWValue(current-pageOffset-1, field[2])
    
    if field[2] == VALUE then 
      value = value
    end
    
    if field[3] == 0x0D then
      newAppId = value + 0x0e50
    end
    
    modifications[#modifications+1] = { field[3], value }
    
    field[4] = value
  end
end

-- Init
function init()
	current, edit, refreshState, refreshIndex = 1, false, 0, 0
  
	pages = {
		runSettingsPage,
	}  
  
end

--run
function runLua(hWin, Key)
  hPWin = hWin
  local result = 0
    
	if Key == 0 then
		result = 0
	elseif Key == 1 then     
    --result = runConfigPage(hWin,Key)
  elseif Key == KEY_ENT then 
      if true == editMode then      
        updateField(fields[current])
      end   
      editMode = not editMode 
  elseif Key == KEY_TAB then
    result = selectField(1)
  elseif Key == KEY_BACKTAB then
    result = selectField(-1)    
  elseif Key == KEY_PGDN_R then
    selectPage(1)
  elseif Key == KEY_PGUP_R then
    selectPage(-1)
  elseif Key == KEY_RTN_R then 
    if true == editMode then
      editMode = not editMode
    else    
      telemetryUnIdle(0x80)       
      clearAll(hWin)
    end 
  else 
    
	end  
  
  drawTitle(hPWin, "SBEC", page, #pages)
  
  pages[page](hWin,Key)
  
  if 0 == appId then
    appId = sport.getAppId()
    if appId < 0x0e50 or appId > 0x0e5f then 
      appId = 0
    else      
      newAppId = appId
      telemetryIdle(0x80)
    end  
  else
    refreshNext()
  end

	return result
 end
