/**
 * Created by termmed on 9/1/14.
 */

function queryComputerPanel(divElement, options) {
    var panel = this;
    panel.showId = false;
    var thread = null;
    var limit = 100;
    var skip = 0;
    var xhrTotal = null;
    var xhrExecute = null;
    panel.currentEx = 0;
    this.divElement = divElement;
    this.options = jQuery.extend(true, {}, options);
    this.options.eclQueryFilter = "inferred";
    this.type = "query-computer";
    panel.subscribers = [];
    panel.totalResults = [];

    if (!componentsRegistry) {
        componentsRegistry = [];
        componentsRegistry.push(panel);
    } else {
        var componentLoaded = false;
        $.each(componentsRegistry, function(i, field) {
            if (field.divElement && field.divElement.id == panel.divElement.id) {
                componentLoaded = true;
            }
        });
        if (componentLoaded == false) {
            componentsRegistry.push(panel);
        }
    }

    this.getDivId = function() {
        return this.divId;
    }

    this.getNextMarkerColor = function(color) {
        //console.log(color);
        var returnColor = 'black';
        if (color == 'black') {
            returnColor = 'green';
        } else if (color == 'green') {
            returnColor = 'purple';
        } else if (color == 'purple') {
            returnColor = 'red';
        } else if (color == 'red') {
            returnColor = 'blue';
        } else if (color == 'blue') {
            returnColor = 'maroon';
        } else if (color == 'maroon') {
            returnColor = 'green';
        }
        //console.log(returnColor);
        globalMarkerColor = returnColor;
        return returnColor;
    }
    //panel.markerColor = panel.getNextMarkerColor(globalMarkerColor);
    panel.markerColor = "asdasdasdas";

    this.subscribe = function(panelToSubscribe) {
        var panelId = panelToSubscribe.divElement.id;
        var alreadySubscribed = false;
        if (!alreadySubscribed) {
            var subscription = channel.subscribe(panelId, function(data, envelope) {
                if (data) {
                    panel.updateCanvas(data);
                }
            });
        }
        // $("#" + panelId + "-ownMarker").show();
        $("#" + panel.divElement.id + "-subscribersMarker").show();
        // $("#" + panelId + "-ownMarker").show();
    }

    this.setUpPanel = function() {
        var context = {
            divElementId: panel.divElement.id
        };
        $(divElement).html(JST["views/developmentQueryPlugin/main.hbs"](context));
        $('#' + panel.divElement.id + '-searchTypeButton').addClass('disabled');
        $(divElement).find('textarea').unbind();
        $(divElement).find('textarea').keypress(function(event) {
            if (event.which == 13) {
                event.preventDefault();
                var s = $(this).val();
                $(this).val(s + "\n");
            }
        });
        $('[data-toggle="tooltip"]').tooltip();

        $('#' + panel.divElement.id + '-searchBoxOption').keyup(function() {
            clearTimeout(thread);
            var $this = $(this);
            thread = setTimeout(function() {
                var optionalTermFilter = $.trim($("#" + panel.divElement.id + "-searchBoxOption").val());
                if (optionalTermFilter.length < 3 && optionalTermFilter.length > 0) {
                    return;
                }
                panel.options.optionalTermFilter = optionalTermFilter;
                panel.doSearch();
            }, 500);
        });


        $('#' + panel.divElement.id + '-clearButton').unbind();
        $('#' + panel.divElement.id + '-clearButton').disableTextSelect();
        $('#' + panel.divElement.id + '-clearButton').click(function() {
            if (xhrExecute != null)
                xhrExecute.abort();
            panel.options.ecl = '';
            panel.options.setEcl(panel.options.ecl);
            //clearOptionalFilters
            panel.options.optionalTermFilter = '';
            panel.options.returnAllOption = false;
            panel.setUpPanel();
        });

        $('#' + panel.divElement.id + '-clearSearchButton').unbind();
        $('#' + panel.divElement.id + '-clearSearchButton').disableTextSelect();
        $('#' + panel.divElement.id + '-clearSearchButton').click(function() {
            $('#' + panel.divElement.id + '-searchBoxOption').val('');
            // panel.clearOptionalFilters();
            panel.options.optionalTermFilter = '';
            var expression = $.trim($("#" + panel.divElement.id + "-ExpText").val());
            if (expression.length !== 0) {
                panel.doSearch();
            }
        });


        $('#' + panel.divElement.id + '-computeInferredButton2').unbind();
        $('#' + panel.divElement.id + '-computeInferredButton2').disableTextSelect();
        $('#' + panel.divElement.id + '-computeInferredButton2').click(function(e) {
            var expression = $.trim($("#" + panel.divElement.id + "-ExpText").val());
            $('#' + panel.divElement.id + '-computeInferredButton2').addClass("disabled");

            // Replace left and right double quote characters with straight quote characters
            if (expression.includes('“') || expression.includes('”')) {
                expression = expression.replaceAll('“', '"').replaceAll('”', '"');
                $("#" + panel.divElement.id + "-ExpText").val(expression);
            }

            panel.execute("inferred", expression, true, null);
            $('#' + panel.divElement.id + '-computeInferredButton2').removeClass("disabled");
        });


        $('#' + panel.divElement.id + '-ExpText').change(function() {
            clearTimeout(thread);
            thread = setTimeout(function() {
                var expression = $.trim($("#" + panel.divElement.id + "-ExpText").val());
                if (typeof panel.options.setEcl !== 'undefined') {
                    panel.options.setEcl(expression);
                }
            }, 500);
        });

        if (panel.options.ecl && panel.options.ecl.length !== 0) {
            $('#' + panel.divElement.id + '-ExpText').val(panel.options.ecl);
        }
        if (panel.options.languageRefsets && panel.options.languageRefsets.length !== 0) {
            panel.setupLanguageRefsetDropdown();
        }
        if (panel.options.modules && panel.options.modules.length !== 0) {
            panel.setupModuleDropdown();
        }
    };
    //setUpPanel end

    panel.setUpPanel();

    this.doSearch = function() {
        var expression = $.trim($("#" + panel.divElement.id + "-ExpText").val());
        if (expression) {
            var view = panel.options.eclQueryFilter ? panel.options.eclQueryFilter : "inferred";
            panel.execute("inferred", expression, true, null);
        }
    }

    this.isSctid=  function(id) {
        if (!id) {
          return false;
        }
        var match = id.match(/^[0-9]+$/);
        return match ? true : false;
      }

    this.execute = function(form, expression, clean, onlyTotal) {
        panel.currentEx++;
        var currentEx = panel.currentEx;
        if (!expression || expression.trim().length === 0) {
            var i18n_enter_ecl_query = jQuery.i18n.prop('i18n_enter_ecl_query');
            $('#' + panel.divElement.id + '-resultInfo').html("<span class='text-danger'><span class='i18n' data-i18n-id='i18n_enter_ecl_query'>"+ i18n_enter_ecl_query + "</span></span>");
            return
        }

        if (onlyTotal) {
            limit = 1;
            skip = 0;
        } else {

            $('#' + panel.divElement.id + '-resultInfo').html("<i class='glyphicon glyphicon-refresh icon-spin'></i>");
            if (clean) {
                $('#' + panel.divElement.id + '-outputBody').html("");
                $('#' + panel.divElement.id + '-outputBody2').html("");
                //Clear footer on reload
                $('#' + panel.divElement.id + '-footer').html("");
                limit = 100;
                skip = 0;
            }
        }
        var data = {
            expression: expression,
            limit: limit,
            skip: skip,
            form: form
        };
        console.log("ecl " + expression);
        panel.lastRequest = data;
        page = skip / limit;
        var expressionURL;
        // var params = "&limit=" + 100;
        var params = "";
        if (panel.options.optionalTermFilter && panel.options.optionalTermFilter.length != 0) {
            // params += "&term=" + panel.options.optionalTermFilter;
            params += "&term=" + encodeURIComponent(panel.options.optionalTermFilter);
        }
        if ( panel.options.returnAllOption ) {
            params += "&returnAll=true";
        }
        expressionURL = options.serverUrl + "/csnoserv/api/explore/ecl?query=" + encodeURIComponent(expression) + params;
        if (xhrExecute != null && !onlyTotal)
            xhrExecute.abort();
        var xhrExecute2 = $.ajax({
            type: "GET",
            headers: {
                'Accept-Language': options.defaultAcceptLanguage ? options.defaultAcceptLanguage : options.languages
            },
            url: expressionURL,
            //timeout: 300000,lasturl
            success: function(result) {
                //if (result.paserResponse.validation) {
                data = result;
                if (!onlyTotal) {
                    $("#" + panel.divElement.id + "-exportResults").removeClass("disabled");
                    var i18n_found_text = jQuery.i18n.prop('i18n_found');
                    var i18n_concepts_text = jQuery.i18n.prop('i18n_concepts');
                    $('#' + panel.divElement.id + '-resultInfo').html("<span class='text-muted small'><span class='i18n' data-i18n-id='i18n_found'>"+ i18n_found_text +"</span> " + data.total + " <span class='i18n' data-i18n-id='i18n_concepts'>"+ i18n_concepts_text +"</span>");
                    var tableTr = $('#' + panel.divElement.id + '-output > table:first > thead > tr');
                    tableTr.html("");
                    //Displaying standard / generic result
                    //Headers
                    tableTr.append($("<th>").append("Concept"));
                    tableTr.append($("<th>").append("Preferred Term"));
                    tableTr.append($("<th>").append("Id"));
                    var queryOutputBody = $('#' + panel.divElement.id + '-outputBody');
                    $.each(data.items, function(i, row) {
                        var inactiveClass = '';
                        if (row.activeStatus == false) {
                            inactiveClass = 'danger';
                        }
                        //Displaying rows
                        queryOutputBody
                            .append("<tr style='cursor: pointer;' class='conceptResult " + inactiveClass + "' data-module='" + row.moduleId + "' data-concept-id='" + row.id + "' data-term='" + (panel.options.displayPreferredTerm ? row.preferredName : row.fullySpecifiedName) + "'>" +
                                "<td>" + (panel.options.displayPreferredTerm ? row.preferredName : row.fullySpecifiedName) + "</td>" +
                                "<td>" + row.preferredName + "</td>" +
                                "<td>" + row.id + "</td>" +
                                "</tr>");
                    });

                    $('#' + panel.divElement.id + '-outputBody').find(".conceptResult").unbind();
                    $('#' + panel.divElement.id + '-outputBody').find(".conceptResult").dblclick(function(event) {
                        var id = $(event.target).closest("tr").attr('data-concept-id');
                        if (panel.isSctid(id)) {
                            var partitionId = id.slice(id.length - 2, id.length - 1);
                            // concept
                            if (partitionId === '0') {
                                channel.publish(panel.divElement.id, {
                                    term: $(event.target).closest("tr").attr('data-term'),
                                    module: $(event.target).closest("tr").attr("data-module"),
                                    conceptId: $(event.target).closest("tr").attr('data-concept-id'),
                                    source: panel.divElement.id,
                                    showConcept: true
                                });
                            } else if (partitionId === '1') { // Description
                                $.ajax({
                                    type: "GET",
                                    headers: {
                                        'Accept-Language': options.defaultAcceptLanguage ? options.defaultAcceptLanguage : options.languages
                                    },
                                    // url: options.serverUrl + "/" + branch + "/descriptions/" + id,
                                    url: options.serverUrl + "/csnoserv/api/lookup/concept?id=" + id,
                                    success: function(result) {
                                        if (result.descriptions) {
                                            channel.publish(panel.divElement.id, {
                                                term: $(event.target).closest("tr").attr('data-term'),
                                                module: $(event.target).closest("tr").attr("data-module"),
                                                conceptId: result.conceptId,
                                                source: panel.divElement.id,
                                                showConcept: true
                                            });
                                        }
                                    }
                                });
                            } else if (partitionId === '2') { // Relationship
                                $.ajax({
                                    type: "GET",
                                    headers: {
                                        'Accept-Language': options.defaultAcceptLanguage ? options.defaultAcceptLanguage : options.languages
                                    },
                                    // url: options.serverUrl + "/" + branch + "/relationships/" + id,
                                    url: options.serverUrl + "/csnoserv/api/lookup/concept?id=" + id,
                                    success: function(result) {
                                        if (result.relationships) {
                                            channel.publish(panel.divElement.id, {
                                                term: $(event.target).closest("tr").attr('data-term'),
                                                module: $(event.target).closest("tr").attr("data-module"),
                                                conceptId: result.sourceConcept.id,
                                                source: panel.divElement.id,
                                                showConcept: true
                                            });
                                        }
                                    }
                                });
                            }
                        }
                    });


                    var i18n_show_text = jQuery.i18n.prop('i18n_show');
                    var i18n_all_text = jQuery.i18n.prop('i18n_all');
                    var i18n_viewing_text = jQuery.i18n.prop('i18n_viewing');
                    var i18n_items_of_text = jQuery.i18n.prop('i18n_items_of');
                    var i18n_total_text = jQuery.i18n.prop('i18n_total');
                    var i18n_showing_all_text = jQuery.i18n.prop('i18n_showing_all');
                    var i18n_matches_text = jQuery.i18n.prop('i18n_matches');
                    var i18n_stated_text = jQuery.i18n.prop('i18n_stated');
                    var i18n_inferred_text = jQuery.i18n.prop('i18n_inferred');

                    var show_html = "<span class='i18n' data-i18n-id='i18n_show'>"+i18n_show_text+"</span>";
                    var all_html = "<span class='i18n' data-i18n-id='i18n_all'>"+i18n_all_text+"</span>";
                    var viewing_html = "<span class='i18n' data-i18n-id='i18n_viewing'>"+i18n_viewing_text+"</span> ";
                    var items_of_html = "<span class='i18n' data-i18n-id='i18n_items_of'>"+i18n_items_of_text+"</span>";
                    var total_html = "<span class='i18n' data-i18n-id='i18n_total'>"+i18n_total_text+"</span>";
                    var showing_all_html = "<span class='i18n' data-i18n-id='i18n_showing_all'>"+i18n_showing_all_text+"</span>";
                    var matches_html = "<span class='i18n' data-i18n-id='i18n_matches'>"+i18n_matches_text+"</span>";
                    var inferredOrStated = null;

                    if (panel.options.eclQueryFilter === 'stated') {
                        inferredOrStated = "<span class='i18n' data-i18n-id='i18n_stated' style='text-transform: lowercase'>"+i18n_stated_text+"</span>";
                    } else {
                        inferredOrStated = "<span class='i18n' data-i18n-id='i18n_inferred' style='text-transform: lowercase'>"+i18n_inferred_text+"</span>";
                    }

                    if (data.items.length != data.total) {
                        $('#' + panel.divElement.id + '-footer').html("<span id='" + panel.divElement.id + "-more' style='cursor:pointer;'>"+show_html+" "+all_html+" ("+viewing_html+ data.items.length + " " + inferredOrStated + " "+items_of_html+" " + data.total + " "+total_html+")</span>");
                    } else {
                        $('#' + panel.divElement.id + '-footer').html(showing_all_html+" " + data.total + " " + inferredOrStated + " "+matches_html);
                        panel.options.returnAllOption = false;
                    }

                    $('#' + panel.divElement.id + '-more').unbind();
                    $('#' + panel.divElement.id + '-more').click(function(e) {
                        panel.options.returnAllOption = true;
                        panel.execute(form, expression, true);
                    });

                } else {
                    onlyTotal(data.items.length);
                }
            }
        }).done(function(result) {
            // done
            xhrExecute2 = null;
        }).fail(function(jqXHR) {
            if (jqXHR && jqXHR.responseJSON && jqXHR.responseJSON.computeResponse && jqXHR.responseJSON.computeResponse.message) {
                $('#' + panel.divElement.id + '-outputBody').html("");
                $('#' + panel.divElement.id + '-outputBody2').html("");
                $("#" + panel.divElement.id + "-footer").html("");
                $('#' + panel.divElement.id + '-resultInfo').html("<span class='text-danger'>" + jqXHR.responseText + "</span>");
            }
            else if (jqXHR && jqXHR.status && (jqXHR.status === 500 || jqXHR.status === 422 || jqXHR.status === 400)) {
                $('#' + panel.divElement.id + '-outputBody').html("");
                $('#' + panel.divElement.id + '-outputBody2').html("");
                $("#" + panel.divElement.id + "-footer").html("");
                $('#' + panel.divElement.id + '-resultInfo').html("<span class='text-danger'>" + jqXHR.responseText + "</span>");
            }
            else if (jqXHR && jqXHR.status === 414) {
                $('#' + panel.divElement.id + '-outputBody').html("");
                $('#' + panel.divElement.id + '-outputBody2').html("");
                $("#" + panel.divElement.id + "-footer").html("");
                $('#' + panel.divElement.id + '-resultInfo').html("<span class='text-danger'>" + "Request is too large" + "</span>");
            }
            else {
                var textStatus = xhrExecute2.statusText;
                if (textStatus != "abort") {
                    if (xhrExecute2.status == 0)
                        textStatus = "timeout";
                    xhrExecute2 = null;
                    if (textStatus === 'timeout') {
                        if (!onlyTotal) {
                            $('#' + panel.divElement.id + '-footer').html("<p class='lead'>Instruction set exceeds maximum allowed time for computation. Some times instructions can be simplified by specifying conditions using concepts closer in the hierarchy to the intended results, avoiding unnecessary selections of large portions of the terminology.</p>");
                            $('#' + panel.divElement.id + '-resultInfo').html("This query cannot be completed in real-time.");
                            //$('#' + panel.divElement.id + '-footer').html("Timeout Error");
                        } else {
                            onlyTotal("Error");
                        }
                    } else {
                        if (!onlyTotal) {
                            $("#" + panel.divElement.id + "-syntax-result").html('<span class="label label-danger">ERROR</span>');
                            $("#" + panel.divElement.id + "-results").html("Error...");
                        } else {
                            onlyTotal("Error");
                        }
                    }
                }
            }
        });
        if (!onlyTotal)
            xhrExecute = xhrExecute2;
    }
}
