-- afkdata bitcoin ticker
-- LICENCE: http://opensource.org/licenses/MIT
-- Steven Cole <steven.j.cole@gmail.com>
-- Some variables
SSID    = ""
APPWD   = ""
MODE    = "1"
CODE    = "USD"
SECOND  = "LTC,ETH,XMR" 
wifiTrys     = 0      -- Counter of trys to connect to wifi
NUMWIFITRYS  = 10    -- Maximum number of WIFI Testings while waiting for connection
--BOARD = "BLACK"
BOARD = "{{COLOR}}"  --either YELLO or BLACK  must be 5 char
local pin = 8
local oldPin = 0
function onChange()
    --print('The pin value has changed to '..gpio.read(pin))
    lcd.clear()
    lcd.put(lcd.locate(0, 0), "Settings Deleted")
    tmr.alarm( 0 , 5000 , 0 , delete_setting )
    --print("settings deleted")
end
if BOARD == "YELLO" then
    gpio.mode(oldPin, gpio.INPUT)
    function CheckOldButton()
       if  gpio.read(oldPin)  == 0  then
         onChange()
       end
      
       tmr.alarm(2, 5000, 0,  CheckOldButton)
    end
    tmr.alarm(2, 5000, 0,  CheckOldButton)
end
if BOARD == "BLACK" then
    gpio.mode(pin, gpio.INT)
    gpio.trig(pin, 'down', onChange)
end
function restart()
    node.restart()  
end
function save_setting(name, value)
  file.open(name, 'w') -- you don't need to do file.remove if you use the 'w' method of writing
  file.writeline(value)
  file.close()
end
function read_setting(name)
  file.open(name)
  result = string.sub(file.readline(value), 1, -2) -- to remove newline character
  file.close()
  return result
end
function delete_setting()
   file.remove("settings")
   restart()
end
function file_exists(name)
   local f=file.open(name,"r")
   if f~=nil then 
     file.close(f) 
     return true 
   else 
     return false
   end
end
-- Change the code of this function that it calls your code.
function launch()
  lcd.clear()
  lcd.put(lcd.locate(0, 0), "Connected")
  lcd.put(lcd.locate(1, 0), "" .. wifi.sta.getip())
  tmr.alarm(0, 1500, 0, function() dofile("http_client.lua") end )
end
function RebootMessage()
    lcd.put(lcd.locate(1, 0), "Reboot Soon...")
	tmr.alarm( 4 , 5000 , 0 , node.restart() )
end
function checkWIFI() 
  if ( wifiTrys > NUMWIFITRYS ) then
    lcd.clear()
    lcd.put(lcd.locate(0, 0), "Connection Fail")
	tmr.alarm( 4 , 300000 , 0 , RebootMessage )
  else
    ipAddr = wifi.sta.getip()
    if ( ( ipAddr ~= nil ) and  ( ipAddr ~= "0.0.0.0" ) )then
      -- lauch()        -- Cannot call directly the function from here the timer... NodeMcu crashes...
      tmr.alarm( 1 , 3000 , 0 , launch )
    else
      -- Reset alarm again
      tmr.alarm( 0 , 2500 , 0 , checkWIFI)
      wifiTrys = wifiTrys + 1
    end 
  end 
end
function swapInstruction1()
lcd.put(lcd.locate(1, 0), "  SSID afkdata  ")
tmr.alarm( 0 , 5000 , 0 , swapInstruction2 )
end
function swapInstruction2()
lcd.put(lcd.locate(1, 0), "I am " .. wifi.ap.getip())
tmr.alarm( 0 , 5000 , 0 , swapInstruction1 )
end
local busid = 0  
local sda= 4     
local scl= 3    
i2c.setup(busid,sda,scl,i2c.SLOW)
local ADR = 0x27
i2c.start(0)
if i2c.address(0, 0x3F, i2c.TRANSMITTER) == true then 
    ADR = 0x3F
end
i2c.stop(0)
--print("ADR in init = "..string.format("%02x", ADR))
lcd = dofile("lcd1602.lua")(ADR)
lcd.light(1)
lcd.locate(0,0)
ipAddr = wifi.sta.getip()
if ( ( ipAddr == nil ) or  ( ipAddr == "0.0.0.0" ) ) then
  if file_exists("settings") then
      dofile("settings")
       
      lcd.put(lcd.locate(0, 0), "Configuring WIFI....")
      wifi.setmode( wifi.STATION )
      wifi.sta.config( SSID , APPWD)
      lcd.put(lcd.locate(1, 0), ""..SSID)
      tmr.alarm( 0 , 2500 , 0 , checkWIFI )
  else
     wifi.setmode(wifi.SOFTAP)
     cfg={}
     cfg.ip="192.168.1.7"
     cfg.netmask="255.255.255.0"
     cfg.gateway="192.168.1.7"
     
     wifi.ap.config({ssid="afkdata"})
     wifi.ap.setip(cfg)
     lcd.put(lcd.locate(0, 0), " ..Setup Mode..")
     swapInstruction1()
  end
else
  launch()
end
srv=net.createServer(net.TCP) 
srv:listen(80,function(conn) 
        conn:on("receive",function(conn,payload) 
                  -- collect data packets until the size of http body meets the Content-Length stated in header
                  if payload:find("Content%-Length:") or bBodyMissing then
                    if tmp_payload then tmp_payload = tmp_payload .. payload else tmp_payload = payload end
                    if (tonumber(string.match(tmp_payload, "%d+", tmp_payload:find("Content%-Length:")+16)) > #tmp_payload:sub(tmp_payload:find("\r\n\r\n", 1, true)+4, #tmp_payload)) then
                        bBodyMissing = true
                        return
                    else
                    payload = tmp_payload
                    if payload:find("Safari") then  -- Safari seems to have & as delimiter so not allowed in settings
                        payload = payload:gsub("&", "")
                    end
                        tmp_payload, bBodyMissing = nil    
                    end
                 end
                 pos =  string.find(payload, "SSID")  
                 print(pos)
                 if pos then                
                     settings = string.sub(payload, pos, string.len(payload))
                     
                     settings = settings:gsub("\r", "")  --find any line return char and remove them 
                     settings = settings:gsub("\n", "")  --will put them back later
                     slash = string.char(92)
                     settings = settings:gsub(slash,slash..slash)    --find any slashes and escape them
                     settings = settings:gsub("\"", "\\\"")    --find any quotes and escape them
                     
                     settings = settings:gsub("SSID=", "SSID=\"")   --start start line quote - keep everthing a string
                     settings = settings:gsub("APPWD=", "\"\r\nAPPWD=\"")
                     settings = settings:gsub("CODE=", "\"\r\nCODE=\"")
                     settings = settings:gsub("SECOND=", "\"\r\nSECOND=\"")
                     settings = settings:gsub("MODE=", "\"\r\nMODE=\"")  --end start line quote - keep everthing a string
                     settings = settings.."\""  --end last string
                     
                     save_setting("settings",settings)
                     conn:send("HTTP/1.1 200 OK\n\n<!DOCTYPE html><html><head><meta charset=\"utf-8\"/></head><body><h1>saved - restarting in 5 seconds</h1></body></html>")
                     tmr.alarm( 0 , 5000 , 0 , restart )
                 else
                 
                    BSelected = ""                  
                    if MODE == "2" then
                        BSelected = "selected"
                    end
                    
                    SSelected = ""
                    if MODE == "3" then
                        SSelected = "selected"
                    end
                    
                    conn:send("HTTP/1.1 200 OK\n\n<!DOCTYPE html><html><head><meta charset=\"utf-8\"/></head>"..
                    "<body><h1>afkdata Admin Page</h1>".. 
                    "<form action=\"\" method=\"POST\" enctype=\"text/plain\" >"..
                    "<br> SSID: <input type=\"text\" name=\"SSID\" value=\""..SSID.."\">"..
                    "<br> Password:<input type=\"password\" name=\"APPWD\"  value=\""..APPWD.."\">".. 
                    "<br><br> Currency:<input type=\"text\" name=\"CODE\"  value=\""..CODE.."\">"..  
                    "<br> Altcoin:<input type=\"text\" name=\"SECOND\"  value=\""..SECOND.."\">".. 
                    "<br><br> Update Notification: <select name=\"MODE\" value=\""..MODE.."\">"..
                    "<option value=\"1\">None</option><option value=\"2\" "..BSelected..">Backlight</option>"..
                    "<option value=\"3\" "..SSelected..">Stars</option>"..
                    "</select><br><br><input type=\"submit\" value=\"Save\" ></form>"..
                    "<br><br>V 1.6</body></html>")                   
                  end
                 
                conn:close() 
                --conn:on('sent',function(conn) conn:close() end)   
            end) 
        end)
