var contractStructure_GUI = function() {
    var DATA, ACTION;
    var $parent, $filter, $tenderHeader, $form;

    return {
        "viewTenderHeader":viewTenderHeader,
        "viewForms":viewForms,

        "showFilterForm":showFilterForm,
        "getFilter":getFilter,
        "setFilter":setFilter,

        "clearResultStatus":clearResultStatus,

        "setWaitStatus":setWaitStatus,
        "clearWaitStatus":clearWaitStatus,

        "showAnswerHistory":showAnswerHistory,
        "removeAnswerHistory":removeAnswerHistory,

        "init":init
    };

    function clearResultStatus() {
         $tenderHeader.html("");
    }

    function clearWaitStatus() {
         $tenderHeader.html("");
    }

    function setWaitStatus() {
         $tenderHeader.html("Please wait ... this may take a while, the more data, the longer!");
    }

    function showFilterForm() {
        var htm = getFilterFormHtm();
        $filter.html(htm);
    }

    function getFilterFormHtm() {
        var htm = "";
        htm += "<table class='params'>";
        htm += "  <tr>";
        htm += "    <td>";
        htm += "      <input class='tenderId' type='text' title='Tender-ID' value=''>";
        htm += "    </td>";
        htm += "    <td>";
        htm += "      <input class='organizationId' type='text' title='Company-ID' value=''>";
        htm += "    </td>";
        htm += "    <td style='text-align: right'><div class='button textButton search'>Search</td>";
        htm += "  </tr>";
        htm += "</table>";
       return htm;
    }

    function getFilter() {
        var tenderId       = $filter.find("input.tenderId").val();
        var organizationId = $filter.find("input.organizationId").val();

        var jsn = {"tenderId": tenderId, "organizationId": organizationId};

        return jsn;
    }

    function setFilter(tenderId, organizationId) {
        $filter.find("input.tenderId").val(tenderId);
        $filter.find("input.organizationId").val(organizationId);
    }

    function viewTenderHeader() {
        var s = new Date();

        var htm = getTenderHeaderHtml();
        $tenderHeader.html(htm);

        util.log.duration(s, "contractStructure: viewTenderHeader");
    }

    function viewForms() {
        var s = new Date();

        var htm = getFormsHtml();
        $form.html(htm);

        util.log.duration(s, "contractStructure: viewForms");
    }

    function showAnswerHistory($element, answerHistoryData) {
        var htm = "";
        if (answerHistoryData.result) {
            htm += "<div class='showAnswerHistoryDiv'>";
            htm += "  <table>";
            htm += "    <tr>";
            htm += "      <th>Value</th>";
            htm += "      <th>Modified By</th>";
            htm += "      <th>Modified At</th>";
            htm += "    </tr>";
            for (var i = 0; i < answerHistoryData.result.length; i++) {
                var resultNode = answerHistoryData.result[i];
                htm += "    <tr class='" + (i%2 == 0 ? "even" : "odd") + "'>";
                htm += "      <td>" + resultNode.value + "</td>";
                htm += "      <td>" + resultNode.emailAddress + " (ID: " + resultNode.modifiedBy + ")" + "</td>";
                htm += "      <td>" + resultNode.modifiedAt + "</td>";
                htm += "    </tr>";
            }
            htm += "  </table>";
            htm += "</div>";
            $element.html(htm);

            $element.removeClass("showAnswerHistoryButton");
            $element.addClass("closeAnswerHistoryButton");
        }
    }

    function removeAnswerHistory($element) {
        $element.html("");

        $element.removeClass("closeAnswerHistoryButton");
        $element.addClass("showAnswerHistoryButton");
    }

    function getTenderHeaderHtml() {
        var htm = "";

        htm += "<table>";
        htm += "  <tr>"
        htm += "    <td>"
        htm += "      <span class='tenderHeaderKey'>Project Name:</span>"
        htm += "      <span class='tenderHeaderValue'>" + DATA.tenderBase.name + "</span>"
        htm += "      <span class='tenderHeaderAppendix'>(ID: " + DATA.tenderBase.id + ")</span>"
        htm += "    </td>"
        htm += "    <td>"
        htm += "      <span class='tenderHeaderKey'>Project Status:</span>"
        htm += "      <span class='tenderHeaderValue'>TBD</span>"
        htm += "    </td>"
        htm += "    <td>"
        htm += "      <span class='tenderHeaderKey'>Contract Status:</span>"
        htm += "      <span class='tenderHeaderValue'>" + DATA.contractBase.contractStatus + "</span>"
        htm += "    </td>"
        htm += "    <td>"
        htm += "      <span class='tenderHeaderKey'>Project role:</span>"
        htm += "      <span class='tenderHeaderValue'>TBD</span>"
        htm += "    </td>"
        htm += "  </tr>"
        htm += "  <tr>"
        htm += "    <td>"
        htm += "      <span class='tenderHeaderKey'>Company:</span>"
        htm += "      <span class='tenderHeaderValue'>" + DATA.contractBase.orgaName + ", "
                                                        + DATA.contractBase.orgaCity + ", "
                                                        + DATA.contractBase.orgaCountry
                                                        + "</span>"
        htm += "    </td>"
        htm += "    <td>"
        htm += "      <span class='tenderHeaderKey'>Company ID:</span>"
        htm += "      <span class='tenderHeaderValue'>" + DATA.contractBase.organizationId + "</span>"
        htm += "    </td>"
        htm += "    <td>"
        htm += "      <span class='tenderHeaderKey'>Hotel Code:</span>"
        htm += "      <span class='tenderHeaderValue'>" + DATA.contractBase.orgaHotelCode + "</span>"
        htm += "    </td>"
        htm += "  </tr>";
        htm += "</table>";
        return htm;
    }


    function getFormsHtml() {
        var htm = "";

        for (var processStepFormKey in DATA.tenderBase.processStepForms) {
            var processStepFormId = processStepFormKey.replace(/^psf#/, "");
            var processStepForm = DATA.tenderBase.processStepForms[processStepFormKey];
            var name = DATA.tenderBase.translations[processStepForm.translationReferenceId].en;
            htm += "<div class='formName'>" + name + " (ID: " + processStepFormId + ")</div>";
            htm += "<table class='formLayout'>";
            var maxColumnCount = 0;
            for (var rowId in processStepForm.layout) {
                var row = processStepForm.layout[rowId];
                htm += "  <tr class='formLayoutRow'>";
                var columnCount = Object.keys(row).length;
                for (var columnId in row) {
                    var column = row[columnId];
                    htm += "    <td class='formLayoutColumn' style='" + column.style + "' width='" + column.width + "'";
                    if (columnCount == 1) {
                        htm += " colspan='@maxColumnCount@'";
                    }
                    htm += ">";
                    for (var ordinal in column.referenceIds) {
                        var bbId = column.referenceIds[ordinal];
                        htm += getBuildingBlockHtml(processStepFormId, bbId);
                    }
                    htm += "    </td>";
                }
                htm += "  </tr>";
                if (columnCount > maxColumnCount) {
                    maxColumnCount = columnCount;
                }
            }
            htm = htm.replace(/@maxColumnCount@/g, maxColumnCount);
            htm += "</table>";
            htm += "<br/>";
        }
        return htm;
    }

    function getBuildingBlockHtml(processStepFormId, bbId) {
        var htm = "";

        var buildingBlock = DATA.tenderBase.buildingBlocks[bbId];
        if (!buildingBlock) {
            util.log.info("Unknown buildingBlockId " + bbId);
            return htm;
        }

        if (!buildingBlock.conditionalBlock) {
            var name = DATA.tenderBase.translations[buildingBlock.translationReferenceId].en + " (ID: " + bbId + ")";
            htm += "<div class='bbName'>" + name + "</div>";
        }
        if (buildingBlock.layout) {
            htm += "<table class='bbLayout'>";
            var maxColumnCount = 0;
            for (var rowId in buildingBlock.layout) {
                var row = buildingBlock.layout[rowId];
                htm += "  <tr class='bbLayoutRow'>";
                var columnCount = Object.keys(row).length;
                for (var columnId in row) {
                    var column = row[columnId];
                    htm += "    <td class='bbLayoutColumn' style='" + column.style + "' width='" + column.width + "'";
                    if (columnCount == 1) {
                        htm += " colspan='@maxColumnCount@'";
                    }
                    htm += ">";
                    for (var ordinal in column.referenceIds) {
                        var questionId = column.referenceIds[ordinal];
                        var question = DATA.tenderBase.questions[questionId];
                        if (!question.hideLabel) {
                            var questName = DATA.tenderBase.translations[question.translationReferenceId].en;
                                htm += "<span class='questionKey'>" + questName + " (" + questionId + "): </span>";
                        }
                        htm += getAnswerHtml(processStepFormId, questionId);
                        htm += "<br/>";
                    }
                    htm += "    </td>";
                }
                htm += "  </tr>";
                if (columnCount > maxColumnCount) {
                    maxColumnCount = columnCount;
                }
            }
            htm = htm.replace(/@maxColumnCount@/g, maxColumnCount);
            htm += "</table>";
        }
        if (buildingBlock.tableQuestionIds) {
            htm += "<table class='bbTable'>";
            var renderHeader = true;
            var htmHeader = "";
            var htmRows = "";
            var formNode = DATA.contractBase.processStepForms[processStepFormId];
            if (formNode) {
                for (var rowIndex in formNode.rows) {
                    var rowNode = formNode.rows[rowIndex];
                    if (rowNode) {
                        htmRows += "<tr>"
                        for (var columnId in buildingBlock.tableQuestionIds) {
                            var questionId = buildingBlock.tableQuestionIds[columnId];
                            var question = DATA.tenderBase.questions[questionId];
                            if (renderHeader) {
                                var questName = DATA.tenderBase.translations[question.translationReferenceId].en;
                                htmHeader += "<th>" + questName + " (" + questionId + ")" + "</th>";
                            }
                            htmRows += "<td>" + getAnswerHtml(processStepFormId, questionId, rowIndex) + "</td>";
                        }

                    }
                    renderHeader = false;
                }
            }
            htm += "<tr>" + htmHeader + "</tr>";
            htm += htmRows;
            htm += "</table>";
        }

        return htm;
    }

    function getAnswerHtml(processStepFormId, questionId, rowIndex) {
        var htm = "";
        rowIndex = rowIndex ? rowIndex : 0;
        var formNode = DATA.contractBase.processStepForms[processStepFormId];
        if (formNode) {
            var rowNode = formNode.rows[rowIndex];
            if (rowNode) {
                var questionNode = rowNode.questions[questionId];
                if (questionNode) {
                    var answerCellNode = questionNode.answerCell;
                    if (answerCellNode) {
                        var answerNode = answerCellNode.answers[0];
                        if (answerNode) {
                            htm += "<span class='answer'>" + getAnswerValue(processStepFormId, questionId, answerNode) + "</span>";
                        }
                    }
                }
            }
        }

        return htm;
    }

    function getAnswerValue(processStepFormId, questionId, answerNode) {
        var depictedValue = answerNode.depictedValue;
        
        var question = DATA.tenderBase.questions[questionId];
        switch (question.initializedType) {
            case 7:
            case 15:
            case 17:
                depictedValue = getYesNo(question, answerNode.value);
                break;
            case 9:
            case 19:
                depictedValue = util.date.formatDateFromMilliseconds(answerNode.value);
                break;
            case 13:
                depictedValue = getRadio(processStepFormId, question, answerNode.value);
                break;
            case 24:
                 depictedValue = getLra(question, answerNode.value);
                 break;
       }
        return depictedValue;
    }

    function getYesNo(question, value) {
        var htm = "<span class='yesNo'>";

        htm += "<span class='yesNoOption";
        if (value == "true") {
            htm += " selected";
        }
        htm += "' data-value='" + value + "'>";
        htm += util.message.get("yes");
        htm += "</span>";
        if (question.style == "LineDirection") {
            htm += "&nbsp";
        } else {
            htm += "<br/>";
        }
        htm += "<span class='yesNoOption";
        if (value == "false") {
            htm += " selected";
        }
        htm += "' data-value='" + value + "'>";
        htm += util.message.get("no");
        htm += "</span>";

        htm += "</span>";

        return htm;
    }

    function getLra(question, value) {
        var htm = "<span class='lra'>";

        htm += "<span class='lraOption";
        if (value == "true") {
            htm += " selected";
        }
        htm += "' data-value='" + value + "'>";
        htm += util.message.get("lra");
        htm += "</span>";
        if (question.style == "LineDirection") {
            htm += "&nbsp";
        } else {
            htm += "<br/>";
        }
        htm += "<span class='lraOption";
        if (value == "false") {
            htm += " selected";
        }
        htm += "' data-value='" + value + "'>";
        htm += util.message.get("non_lra");
        htm += "</span>";

        htm += "</span>";

        return htm;
    }

    function getRadio(processStepFormId, question, value) {
        var htm = "<div class='radio'>";

        var answerRanges = question.answerRanges;
        if (question.type == 16) {
            var initializedQuestion = DATA.tenderBase.questions[question.initializedQuestionId];
            if (initializedQuestion) {
                answerRanges = initializedQuestion.answerRanges;
            }
        }

        for (var answerRangeIndex in answerRanges) {
            var conditionalBlockHtm = "";
            var answerNode = answerRanges[answerRangeIndex];
            if (answerNode) {
                htm += "<span class='radioOption";
                if (answerNode.value == value) {
                    htm += " selected";
                    conditionalBlockHtm = getBuildingBlockHtml(processStepFormId, answerNode.conditionalBlockId);
                }
                htm += "' data-value='" + answerNode.value + "'>";
                htm += answerNode.depictedValue;
                htm += conditionalBlockHtm;
                htm += "</span>";
                if (question.style == "LineDirection") {
                    htm += "&nbsp";
                } else {
                    htm += "<br/>";
                }
            }
        }

        htm += "</div>";

        return htm;
    }

    function initStructure() {
        var htm = "";
        htm += '<div class="filter"></div>';
        htm += '<br />';
        htm += '<div class="tenderHeader"></div>';
        htm += '<br />';
        htm += '<div class="form"></div>';

        $parent = $(DATA.guiParentSelector).first();
        $parent.addClass("contractStructure");
        $parent.html(htm);

        $filter = $parent.find(".filter");
        $tenderHeader = $parent.find(".tenderHeader");
        $form = $parent.find(".form");
    }

    function init(contractStructure) {
        DATA = contractStructure.DATA;
        ACTION = contractStructure.ACTION;
        initStructure();
    }

}
