require("luamods/cgi")
require("luamods/layout")
require("luamods/command")
require("luamods/db")
require("config/rsm_conf")

-- Get all the config from the xml as well as test various aspects
-- Test what kind of user accessed the bord (admin or not)
userLevel = db.getPriv(layout.username) or 1

if (userLevel == 1) then
    buttonControl = " disabled"
    inputControl = " readonly"
    scriptControl = "//"
else
    buttonControl = ""
    inputControl = ""
    scriptControl = ""
end

-- Set layout of the header and footer
header = layout.getHeader()
footer = layout.getFooter()

-- Get message config from xml file
smsProfileConfig = command.ex([[cat ]]..rsm_conf.gsd_xml_path) or ""

-- Delete a message
if (cgi.post.deleteGsdButton == "Delete Message") and (userLevel ~= 1) then

    postMsgId = cgi.post.file or ""
    postMsgId = postMsgId:gsub("[^%w%.]+","")

    for messages in smsProfileConfig:gmatch("<message.*</message>") do
        local newMessage = ""

        for message in messages:gmatch("(<message.-</message>)") do
            local id = message:match("id=\"(%d)\"")
            if id ~= postMsgId then
                newMessage = newMessage.."\n"..message
            end
        end
    
        smsProfileConfig = smsProfileConfig:gsub("<message.*</message>", newMessage)
    end

    command.writefile(rsm_conf.gsd_xml_path, smsProfileConfig)

    -- Restart daemon using the xml
    command.ex(rsm_conf.gsd_restart)

    label = cgi.post.msgLabelInput or ""
    -- Stop here
    content = [[
                    <div id="info">
                        <div style="background:url(images/busconfig.png); background-size:32px; background-repeat:no-repeat; background-position: 20px center;">
                            <center><h1>Edit Message</h1></center>
                        </div>
                    </div>
                    <div id="info">
                        <center>
                            <h2><img src="images/ok.png"/> Message Deleted</h2>
                            Message : "]]..label..[[" with id : "]]..postMsgId..[[" has been removed.<br><br>
                            <a href="gsd.lua">Back to Bus Configuration</a>
                        </center>
                    </div>
]]
    print(header..content..footer)
    os.exit()
end

-- Update the config string if values were posted for GSM Sms Daemon.
if (cgi.post.saveGsdButton == "Save and Apply") and (userLevel ~= 1) then
  
    postMsgId = cgi.post.file or ""
    if (postMsgId == "") then
        createdNew = 1
    else
        postMsgId = postMsgId:gsub("[^%w%.]+","")
        createdNew = 0
    end
  
    local newMsgLabel = cgi.post.msgLabelInput or ""
    local newMsgText = cgi.post.msgTextInput or ""
    local newMsgShowSite = (cgi.post.msgShowSiteInput == "on")
    newMsgShowSite = (newMsgShowSite and "yes" or "no")
    
    local newMsgRecepients = {}
    
    for count = 1,10 do
        if (cgi.post["msgRecepientInput"..count] ~= nil)then
            recepientNumber = cgi.post["msgRecepientInput"..count]
            table.insert(newMsgRecepients, recepientNumber)
        end
    end
    
    if (createdNew == 0) then
      
        for setting in smsProfileConfig:gmatch("<message%s*(id=.->)%s-</message>") do
            local prevMsgId = setting:match("id=\"(.-)\"")
            local prevMsgLabel = setting:match("label=\"(.-)\"")
            
            if(prevMsgId == postMsgId) then
                local prevSetting = [[<message id="]]..postMsgId..[[" .-</message>]]
                
                if (prevMsgLabel ~= nil and newMsgLabel ~=nil) then
                    setting = setting:gsub(prevMsgLabel,newMsgLabel)
                end
                
                local prevMsgText = setting:match[[<text_message>.-</text_message>]]
                if (prevMsgText ~= nil and newMsgText ~=nil) then
                    setting = setting:gsub(prevMsgText,[[<text_message>]] ..newMsgText .. [[</text_message>]])
                end
                
                local prevMsgShowSite = setting:match[[<include_site>.-</include_site>]]
                if (prevMsgShowSite ~= nil and newMsgShowSite ~=nil) then
                    setting = setting:gsub(prevMsgShowSite,[[<include_site>]] ..newMsgShowSite .. [[</include_site>]])
                end
                
                local replaceRecepients = ""
                for i,recepientNumber in ipairs(newMsgRecepients) do
                    replaceRecepients = replaceRecepients.."\t\t"..[[<recepient>]]..recepientNumber..[[</recepient>]].."\n"
                end
                
                local prevRecepients = setting:match[[<cell_numbers>.-</cell_numbers>]]
                if (prevRecepients ~= nil) then
                    setting = setting:gsub([[<cell_numbers>.-</cell_numbers>]],[[<cell_numbers> ]].."\n"..replaceRecepients.."\t"..[[ </cell_numbers>]])
                end
                
                setting = "<message "..setting.."\n".."</message>"
                smsProfileConfig = smsProfileConfig:gsub(prevSetting, setting)
            end
        end
    else
        -- Get the last id assigned and iterate for new Id
        nextId = 1
        for match in smsProfileConfig:gmatch("<message%s*(id=.->)%s-</message>") do
            local messageId = match:match("id=\"(.-)\"") 
            nextId = messageId + 1
        end
        -- Create new camera and replace end </profile> tag with it

        local newMsgid = string.format("%d",nextId)
        newMessage = [[
    <message id="]]..newMsgid..[[" label="]]..newMsgLabel..[[">
        <text_message>]]..newMsgText..[[</text_message>
        <cell_numbers>
        ]]
        
        local replaceRecepients = ""
        for i,recepientNumber in ipairs(newMsgRecepients) do
            replaceRecepients = replaceRecepients.."\t"..[[<recepient>]]..recepientNumber..[[</recepient>]].."\n"
        end
        
        newMessage = newMessage .. 
            replaceRecepients ..[[
        </cell_numbers>
        <include_site>]]..newMsgShowSite..[[</include_site>
    </message>
</profile>
        ]]
        smsProfileConfig = smsProfileConfig:gsub("</profile>", newMessage)
        postMsgId = newMsgid
    end
    
    command.writefile(rsm_conf.gsd_xml_path, smsProfileConfig)
    
    -- Restart the sms daemon to enable changes
    command.ex(rsm_conf.gsd_restart)
    
    -- Set the filename to the new file...which should be the newly added camera id
    editMsgId = postMsgId
    saved = 1
    mode = "edit"
    
-- Check if the file needs to be edited or changed
else
    editMsgId = cgi.get.file or ""
    if (editMsgId == "") then
        mode = "new"
    else
        editMsgId = editMsgId:gsub("[^%w%.]+","")
        mode = "edit"
    end
end


if (mode == "edit") then
    -- Get all the message config blobs
    messageConfs = {}
    for match in smsProfileConfig:gmatch("<message%s*(id=.->)%s-</message>") do
        local messageId = match:match("id=\"(.-)\"")
        local messageLabel = match:match("label=\"(.-)\"")
        table.insert(messageConfs, [[MessageId: ]]..messageId..[[\n]]..[[MessageLabel: ]]..messageLabel..[[\n]]..match)
    end

    -- Populate table with config for desired message
    messageBlob = {}
    labelLength = 45
    for i,configBlob in pairs(messageConfs) do
        messageBlob.msgId = configBlob:match([[MessageId:%s+(.-)%s-\n]]) or ""
        if (messageBlob.msgId == editMsgId) then
            messageBlob.msgLabel = configBlob:match([[MessageLabel:%s+(.-)%s-\n]]) or ""
            messageBlob.msgText = configBlob:match([[<text_message>%s-(.-)%s-</text_message>]]) or ""
            messageBlob.msgShowSite = configBlob:match([[<include_site>%s-(.-)%s-</include_site>]]) or ""
            messageBlob.msgShowSite = (messageBlob.msgShowSite == "yes")
            
            local recepientCount = 0
            local tempRecepients = configBlob:match([[<cell_numbers>%s-(.-)%s-</cell_numbers>]]) or ""
            messageBlob.msgRecepients = {}
            
            for match in tempRecepients:gmatch("<recepient>%s*(.-)%s-</recepient>") do
                recepientCount = recepientCount + 1
                table.insert(messageBlob.msgRecepients, match)
            end
            messageBlob.msgRecepientCount = recepientCount

            -- Determine Length of message label input text
            if (#messageBlob.msgLabel < 45) then
                labelLength = #messageBlob.msgLabel
            end
            
            break
        end
    end
else
    -- Populate table with config for desired message
    messageBlob = {}
    labelLength = 20
    messageBlob.msgId = ""
    messageBlob.msgLabel = ""
    messageBlob.msgText = ""
    messageBlob.msgShowSite = false
    messageBlob.msgRecepients = {}
    messageBlob.msgRecepientCount = 0
end
  

-- Page content (the view)
content = ""

-- Set the content of the header
if (mode == "new") then
    content = [[
                    <div id="info">
                        <center><h1>Add Message</h1></center>
                    </div>
                    <h3>Adding new message :</h3>
    ]]
else
    content = [[
                    <div id="info">
                        <center><h1>Edit Message</h1></center>
                    </div>
                    <h3>Editing message "]]..messageBlob.msgLabel..[[" with message id "]]..editMsgId..[[":</h3>
    ]]
end

content = content .. [[
                    <script>
                        function toggleVis(target)
                        {
                            if (target.style.display == "none")
                            {
                                target.style.display = "inline-block";
                            }
                            else
                            {
                                target.style.display = "none";
                            }
                            return false;
                        }
                    </script>
]]

-- If admin give a note that the page can't be edited
if (userLevel == 1) then
    content = content .. [[
                    <center><b>Note:</b> Editing this section requires administrator privileges.</center><br>
    ]]
end

-- If no config was detected notify user
if (smsProfileConfig == "") then
    -- Don't bail, just warn
    content = content .. [[
                    <div id="info">
                        <center>
                            <h2><img src="images/warning.png"/> Config file(s) missing</h2>
                            Cannot read the following file(s) required for editing messages:<br><br>
                            <span style="display: inline-block; text-align: left; width: 400px;">
                                <ul>
    ]]


    if (smsProfileConfig == "") then
        messageBroken = 1
        content = content .. [[
                                    <li>Message Config - ]]..rsm_conf.gsd_xml_path..[[</li>
        ]]
    end
    
    content = content .. [[
                                </ul>
                            </span>
                        </center>
                    </div>
    ]]
end

-- Scripts
content = content .. [[
 <script>
                        var doValidate = 0;
                        function validateForm(form)
                        {
                        // Test if submit button was pressed to post form
                            if (form.getAttribute('submitted'))
                            {
                                return false;
                            }
                            
                            if (!doValidate)
                            {
                                form.setAttribute('submitted','true');
                                return true;
                            }
                            doValidate = 0;
                            
                        // Test text inputs to ensure that the fields were entered
                            var inputs = form.getElementsByTagName("input");

                            var inputIdx;
                            var warning;
                            var input_count = 0;
                            var errors = false;
                            for (inputIdx = 0; inputIdx < inputs.length; inputIdx++)
                            {
                                // Don't validate buttons.
                                if(inputs[inputIdx].type != "text")
                                {
                                    continue;
                                }

                                warning = document.getElementById("warning"+inputIdx);
                                if (inputs[inputIdx].value == "")
                                {
                                    if (!warning)
                                    {
                                        warning = document.createElement("span");
                                        warning.id = "warning"+inputIdx;
                                        warning.innerHTML = " <img src='images/warning.png' alt='Cannot be blank' title='Cannot be blank'/> Cannot be blank";
                                        inputs[inputIdx].parentNode.appendChild(warning);
                                    }
                                    errors = true;
                                }
                                else
                                {
                                    if (warning)
                                    {
                                        warning.parentNode.removeChild(warning);
                                    }
                                }
                            }
                            
                        //Test text area to ensure message text was entered
                            var textArea = document.getElementById("msgTextArea");
                            warning = document.getElementById("warning"+inputIdx);
                            
                            if(textArea.value  == '')
                            {
                                if (!warning)
                                {
                                    warning = document.createElement("span");
                                    warning.id = "warning"+inputIdx;;
                                    warning.innerHTML = " <img src='images/warning.png' alt='Cannot be blank' title='Cannot be blank'/> Cannot be blank";
                                    textArea.parentNode.appendChild(warning);
                                }
                                errors = true;
                            }
                            else if(textArea.value.length > 100)
                            {
                                if (!warning)
                                {
                                    warning = document.createElement("span");
                                    warning.id = "warning"+inputIdx;;
                                    warning.innerHTML = " <img src='images/warning.png' alt='Message too long' title='Message too long'/> Message too long";
                                    textArea.parentNode.appendChild(warning);
                                }
                                errors = true;
                            }
                            else
                            {
                                if (warning)
                                {
                                    warning.parentNode.removeChild(warning);
                                }
                            }

                        //Test to ensure at least one recepient was added
                            var field_area = document.getElementById("recepient_list");
                            var all_inputs = field_area.getElementsByTagName("input"); //Get all the input fields in the given area.
                            var count = all_inputs.length;
                            
                            inputIdx = inputIdx + 1;
                            warning = document.getElementById("warning"+inputIdx);
                                
                            if (count == 0)
                            {
                                if (!warning)
                                {
                                    warning = document.createElement("span");
                                    warning.id = "warning"+inputIdx;;
                                    warning.innerHTML = " <img src='images/warning.png' alt='Cannot be empty' title='Cannot be empty'/> Cannot be empty";
                                    field_area.parentNode.appendChild(warning);
                                }
                                errors = true;
                            }
                            else
                            {
                                if (warning)
                                {
                                    warning.parentNode.removeChild(warning);
                                }
                            }
                            
                        //Test to ensure that only numeric charaters were entered for recepients
                            if(!errors)
                            {
                                var recepientIdx;
                                
                                for (recepientIdx = 0; recepientIdx < count; recepientIdx++)
                                {
                                    var numberEntered = all_inputs[recepientIdx].value;
                                    inputIdx = inputIdx + 1;
                                    warning = document.getElementById("warning"+inputIdx);
                                    
                                    if (!numberEntered.match(/^\d+$/))
                                    {
                                        if (!warning)
                                        {
                                            warning = document.createElement("span");
                                            warning.id = "warning"+inputIdx;
                                            warning.innerHTML = " <img src='images/warning.png' alt='Only numeric charaters allowed' title='Only numeric charaters allowed'/> Only numeric charaters allowed";
                                            all_inputs[recepientIdx].parentNode.appendChild(warning);
                                        }
                                        errors = true;
                                    }
                                    else
                                    {
                                        if (warning)
                                        {
                                            warning.parentNode.removeChild(warning);
                                        }
                                    }
                                }
                            }
                            
                            
                        //Test to see if any errors popped up, if it did don't post the form but show warning
                            if (errors)
                            {
                                alert("Not all fields have been filled in.\nPlease enter/select valid values for the indicated fields.");
                                return false;
                            }
                            else
                            {
                                form.setAttribute('submitted','true');
                                return true;
                            }
                        }
                        
                        function addField(field,limit)
                        {
                            if(!document.getElementById) return; //Prevent older browsers from getting any further.
                            var field_area = document.getElementById(field+"_list");
                            var all_inputs = field_area.getElementsByTagName("input"); //Get all the input fields in the given area.
                            var count = all_inputs.length;
                            if(count+1 > limit && limit > 0) return;
                            
                            if (document.createElement)
                            {
                                var li = document.createElement("li");
                                if (field == "recepient")
                                {
                                    li.innerHTML = "<label style=\"width:250px; display: inline-block; text-align: left; vertical-align: middle;\">Recepient :</label>";
                                    li.innerHTML = li.innerHTML + " <input type=\"text\" name=\"msgRecepientInput"+(count+1)+"\" value=\"\" ]]..inputControl..[[ size=\"15\"/>";
                                    li.innerHTML = li.innerHTML + " <a style=\"cursor:pointer;color:blue;\" onclick=\" ]]..scriptControl..[[ removeField(this, \'recepient\');\"> <img src=\"images/trash.png\" alt=\"Delete\" title=\"Delete\"/></a>"
                                    li.innerHTML = li.innerHTML + "<br>"
                                    

                                }
                                field_area.appendChild(li);
                            }
                        }
                        
                        function removeField(node,field)
                        {
                            node.parentNode.parentNode.removeChild(node.parentNode);
                            var field_area = document.getElementById(field+"_list");
                            var all_inputs = field_area.getElementsByTagName("input"); //Get all the input fields in the given area.
                            var loop;
                            
                            if (field == "recepient")
                            {
                                for (loop = 0; loop < all_inputs.length; loop++)
                                {
                                    all_inputs[loop].name = "msgRecepientInput"+(loop+1); 
                                }                                    
                            }
                        }

                    </script>
]]


-- Main form div
content = content .. [[
                    <div class="formLayoutfull">
]]

-- Test if xml file is there, then setup main form
if (messageBroken == 1) then
    content = content .. [[
                        <h3><img src="images/warning.png" alt="message config missing" title="message config missing"> Messages:</h3>
                        Cannot determine path to messages.
]]
else
    -- Create main message form split into the message part and recepients part
    -- Message part
    content = content .. [[
                        <form name="messageForm" action="gsd_edit.lua" method="post" onsubmit="return validateForm(this);">
                            <h3>Message Settings:</h3>
                            <div>
                              <label style="width:250px; display: inline-block; text-align: left; vertical-align: middle;">Message Label:</label>
                              <input type="text" name="msgLabelInput" value="]]..messageBlob.msgLabel..[["]]..inputControl..[[ size="]]..labelLength..[["/>
                            </div>
                            <br>

                            <div>
                              <label style="width:250px; display: inline-block; text-align: left; vertical-align: middle;">Message Text:</label>
                              <textarea rows="4" cols="40" name="msgTextInput" style="vertical-align: middle;" ]]..inputControl..[[ id="msgTextArea">]]
                                  ..messageBlob.msgText..[[</textarea>
                            </div>
                            <br>

                            <div>
                              <label style="width:250px; display: inline-block; text-align: left; vertical-align: middle;">Display Site Name in Message:</label>
                              <input type="hidden" value="off" name="msgShowSiteInput" />
                              <input type="checkbox" value="on" name="msgShowSiteInput" style="vertical-align: middle;" ]]..inputControl..[[ ]] .. (messageBlob.msgShowSite and "checked" or "")  .. [[></input>
                            </div>
                            <br><br><hr>
    ]]
    -- Recepients part
    content = content .. [[
                            <br>
                            <h3>Recepient Settings:</h3>
                            <div>
                                <ol id="recepient_list">
    ]]
    
    for i,recepientIdx in pairs(messageBlob.msgRecepients) do
        content = content .. [[
                                    <li>
                                        <label style="width:250px; display: inline-block; text-align: left; vertical-align: middle;">Recepient :</label>
                                        <input type="text" name="msgRecepientInput]]..i..[[" value="]]..recepientIdx..[["]]..inputControl..[[ size="15"/>
                                        <a style="cursor:pointer;color:blue;" onclick=" ]]..scriptControl..[[ removeField(this, 'recepient');"> <img src="images/trash.png" alt="Delete" title="Delete"/></a>
                                        <br>
                                    </li>
        ]]
    end
                                 -- 
    content = content .. [[      
                                </ol>
                            </div>
                            <br>
                            <input type="button" name="addNewRecepient" value="Add new recepient" ]]..buttonControl..[[ onclick="addField('recepient', 10);"/>
                            <br><br><hr>
                            
                            <br>
    ]]
    
    -- Finally the three buttons to use the form
    content = content .. [[ 
                            <input type="hidden" name="file" value="]]..editMsgId..[["/>
                            <input type="button" name="backGsdButton" value="Back to Sms Profile" ]]..buttonControl..[[ onclick="window.location.assign('gsd.lua');"/>
                            <input type="submit" name="saveGsdButton" value="Save and Apply" ]]..buttonControl..[[ onclick="doValidate = 1;"/>
    ]]
    
    -- Add delete button if in edit mode
    if (mode == "edit") then
        content = content .. [[
                            <input type="submit" name="deleteGsdButton" value="Delete Message"]]..buttonControl..[[ onclick="return confirm('Are you sure you want to delete this message?');"/>
        ]]
    end
    
    -- Show if add/update was successful
    if (saved == 1) then
        if (createdNew == 1) then
            content = content .. [[
                            <b><img src="images/ok.png"/> Saved new message </b><br><br>
            ]]
        else
            content = content .. [[
                            <b><img src="images/ok.png"/> Changes saved </b><br><br>
            ]]
        end
    end
    
    content = content .. [[
                        </form>
    ]]

end
    

-- End of main form div
content = content .. [[
                    </div>
]]

-- Show hyperlink to xml file
if (mode == "edit") then
    if (messageBroken ~= 1) then
        smsProfileConfig = smsProfileConfig:gsub("<","&lt;")
        smsProfileConfig = smsProfileConfig:gsub(">","&gt;")
        content = content .. [[
                        <br><img src="images/magnify.png"/> <a href="javascript:void(0)" onclick="toggleVis(document.getElementById('smsProfileConfig'));">View ]]..rsm_conf.gsd_xml_path..[[</a></a><br>

                        <div id="smsProfileConfig" style="display: none;">
                            <pre class="formLayoutfull">]]..smsProfileConfig..[[</pre>
                        </div>
        ]]
    end
end

--Post webpage
html = header
html = html..content
html = html..footer

print(html)