define([
    'Global',
    'Resources',
    'UserSession',
    'Facilities',
    'Organisms',
    'Antibiogram',
    'AntibiogramMatrix',
    'AntibiogramSummaryView',
    'dataTables',
    'fixedColumns',
    'Text!../html/templates/antibiogramSearch.html'
],
    function (Global, resources, UserSession, Facilities, Organisms, Antibiogram, AntibiogramMatrix, AntibiogramSummaryView, dataTables, fixedColumns, AntibiogramSearchTemplate) {
        return Backbone.View.extend({
            tagName: 'div',
            id: 'antibiogram-search',
            attributes: {'data-role': 'none'},
            recentLocations: readLocationsFromStorage('recentLocations'),
            recentOrganisms: readLocationsFromStorage('recentOrganisms'),
            facilitySelectTriggered: false,
            lowIsolateThreshold: 30,

            initialize: function () {
                this.template = _.template(AntibiogramSearchTemplate);
                this.userSession = new UserSession();
            },

            convertFacilityToAutocompleteItem: function (facility, itemCategory) {
                return {
                    label: facility.name + ' - ' + facility.city + ' - ' + facility.state,
                    value: facility.name,
                    category: itemCategory
                };
            },

            convertFacilitiesToAutocompleteList: function (recentLocations, facilities) {
                var mostRecentListLength = recentLocations.length,
                    listLength = facilities.length,
                    autocompleteList = [],
                    mostRecentFacilitiesCategoryText = "Most Recent Facilities",
                    searchResultsText = "Search Results",
                    i = -1;

                for (i; ++i < mostRecentListLength;) {
                    autocompleteList[i] = this.convertFacilityToAutocompleteItem(recentLocations[i], mostRecentFacilitiesCategoryText);
                }

                for (i = -1; ++i < listLength;) {
                    autocompleteList[i + mostRecentListLength] = this.convertFacilityToAutocompleteItem(facilities.models[i].toJSON(), searchResultsText);
                }

                return autocompleteList;
            },

            findFacilityByName: function (recentLocations, name) {
                // if (typeof recentLocations !== 'undefined' && recentLocations) {
                    var listLength = facilities.length,
                        mostRecentListLength = recentLocations.length,
                        i = -1;

                    for (i; ++i < mostRecentListLength;) {
                        // if (name === recentLocations[i].name) {
                        if (name.indexOf(recentLocations[i].name) === 0) {
                            return result = recentLocations[i];
                        }
                    }

                    for (i = -1; ++i < listLength;) {
                        // if (name === facilities.models[i].get('name')) {
                        if (name.indexOf(facilities.models[i].get('name')) === 0) {
                            return facilities.models[i];
                        }
                    }

                    return null;
                // }
            },

            convertOrganismToAutocompleteItem: function (organism, itemCategory) {
                return {
                    label: organism.name,
                    value: organism.name,
                    category: itemCategory
                };
            },

            convertOrganismsToAutocompleteList: function (recentOrganisms, organisms, organismGroups) {
                var mostRecentListLength = recentOrganisms.length,
                    organismLength = organisms.length,
                    organismGroupLength = organismGroups.length,
                    autocompleteList = [],
                    mostRecentOrganismsCategoryText = "Most Recent Organisms",
                    organismResultsText = "Organisms",
                    organismGroupResultsText = "Organism Groups",
                    i = -1;

                for (i; ++i < mostRecentListLength;) {
                    autocompleteList[i] = this.convertOrganismToAutocompleteItem(recentOrganisms[i], mostRecentOrganismsCategoryText);
                }

                for (i = -1; ++i < organismLength;) {
                    autocompleteList[i + mostRecentListLength] = this.convertOrganismToAutocompleteItem(organisms[i].attributes, organismResultsText);
                }
                
                for (i = -1; ++i < organismGroupLength;) {
                    autocompleteList[i + mostRecentListLength + organismLength] = this.convertOrganismToAutocompleteItem(organismGroups[i].attributes, organismGroupResultsText);
                }

                return autocompleteList;
            },

            findOrganismByName: function (recentOrganisms, name) {
                if (typeof recentOrganisms !== 'undefined' && recentOrganisms) {
                    var listLength = organisms.length,
                        mostRecentListLength = recentOrganisms.length,
                        i = -1;

                    for (i; ++i < mostRecentListLength;) {
                        if (name === recentOrganisms[i].name) {
                            return recentOrganisms[i];
                        }
                    }

                    for (i = -1; ++i < listLength;) {
                        if (name === organisms.models[i].get('name')) {
                            return organisms.models[i];
                        }
                    }

                    return null;
                }
            },

            clearErrors: function () {
                $('#errorDiv').popup('close');
                $('#errorDiv p').html('');
            },

            showErrorMessage: function (text) {
                $('#errorDiv p').html(text);
                $('#errorDiv').popup('open');
            },

            isAntibiogramSearch: function (antibiogramSearch , url) {
                return url.indexOf(antibiogramSearch) !== -1;
            },
            enableAutoComplete: function () {
                var that = this,
                    $container = this.$el;
                $.widget("custom.catcomplete", $.ui.autocomplete, {
                    _renderMenu: function (ul, items) {
                        var self = this,
                            currentCategory = "";
                        $.each( items, function( index, item ) {
                            if ( item.category != currentCategory ) {
                                ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
                                currentCategory = item.category;
                            }
                            self._renderItemData( ul, item );
                        });
                    }
                });
                if(!this.userSession.isLoggedIn()){
                    $("#organismName", $container).attr("disabled", "disabled");
                }
                
                function populateFacility(selectedFacility) {

                    var facility = that.findFacilityByName(that.recentLocations, selectedFacility),
                        facilityName,
                        facilityCode;
                    if (selectedFacility && facility) {
                        if (typeof facility.name !== 'undefined' && facility.name) {
                            facilityName = facility.name;
                        } else {
                            facilityName = facility.get('name')
                        }
                    
                        if (typeof facility.facilityCode !== 'undefined' && facility.facilityCode) {
                            facilityCode = facility.facilityCode;
                        } else {
                            facilityCode = facility.get('facilityCode')
                        }
                        that.antibiogram = new Antibiogram(facilityCode);
                    
                        $("#facilityName").val(facilityName);
                        $("#main").attr('data-valid-facility',facilityName);
                        $('#facilityCode').val(facilityCode);
                        $("#organismName").textinput("enable");
                        that.checkInputFields();
                        that.clearErrors();
                        $container.find(":jqmData(role='status')").hide();
                    }
                    else {
                        that.showErrorMessage('Please select a valid VA Hospital Location from the autocomplete results');
                    }
                    
                }

                $('#facilityName').catcomplete({
                    delay: 100,
                    minLength: 2,
                    source: function (request, response) {
                        var generatedUrl = resources.get('facility-service').get('href');
                        generatedUrl += "?parentFacilitiesOnly=true&term=" + request.term;

                        facilities.fetch({
                            url: generatedUrl,
                            success: function (collection) {
                                response(that.convertFacilitiesToAutocompleteList(that.recentLocations, collection));
                                $(".ui-menu-item").tap(function () {
                                    // This is a patch for the Galaxy Note, since the select event doesn't get triggered on that device.
                                    if (!that.facilitySelectTriggered) {
                                        var selectedFacility = $(this).text();
                                        populateFacility(selectedFacility);
                                    }
                                });
                            },
                            statusCode: {
                                302 : function() {
                                    loginRedirect();
                                },
                                500 : function() {
                                    that.showErrorMessage('There was a problem getting information from the server. (facilities.fetch)');
                                }
                            }
                        });
                    },
                    select: function(event, ui) {
                        that.facilitySelectTriggered = true; // Flag to indicate the select event was triggered. Won't be set to true on the Galaxy Note.
                        var selectedFacility = ui.item.value;
                        populateFacility(selectedFacility);
                        $("#facilityName").blur();
                    }
                });

                organisms = new Organisms(),
                // Sort organisms by name
                organisms.comparator = function(organism) {
                    return organism.get("name");
                },

                $('#organismName').catcomplete({
                    delay: 100,
                    minLength: 2,
                    source: function( request, response ) {
                        var generatedUrl = that.antibiogram.get('antibiogram-facility-organism').href;
                        generatedUrl += "?term=" + request.term;

                        organisms.fetch({
                            url: generatedUrl,
                            success: function(collection) {
                                var organisms = collection.where({"object-type": "Organism"}),
                                    organismGroups = collection.where({"object-type": "OrganismGroup"});
                                response(that.convertOrganismsToAutocompleteList(that.recentOrganisms, organisms, organismGroups));
                            },
                            statusCode: {
                                302 : function() {
                                    loginRedirect();
                                },
                                500 : function() {
                                    that.showErrorMessage('There was a problem getting information from the server. (organisms.fetch)');
                                }
                            }
                        });
                    },
                    select: function(event, ui) {
                        var selectedOrganism = ui.item.value;
                        var organism = that.findOrganismByName(that.recentLocations, selectedOrganism);
                        if (selectedOrganism && organism) {
                            var organismId,
                                objectType = organism.get("object-type");
                                $('#objectType').val(objectType);
                            if (typeof organism.id !== 'undefined' && organism.id) {
                                organismId = organism.id;
                            } else {
                                organismId = organism.get('id');
                            }
                            $('#organismId').val(organismId);
                            that.checkInputFields();
                            that.clearErrors();
                            $container.find(":jqmData(role='status')").hide();
                            $('#organismName').blur();
                        } else {
                            that.showErrorMessage('Please select a valid Organism from the autocomplete results');
                        }
                    }
                });
            },
            render: function(fromMainLoad) {
                var that = this,
                    $container = this.$el,
                    selectedFacilityName = $('#facilityName', $container).val(),
                    selectedFacilityCode = $('#facilityCode', $container).val();

                $container.empty().html(this.template());

                var currenturl = $(location).attr('href');
                if (this.isAntibiogramSearch('/#antibiogram-search', currenturl)) {
                    $('#organismName', $container).parent().removeClass("ui-screen-hidden");
                } else {
                    $('#organismName', $container).parent().addClass("ui-screen-hidden");
                }
                facilities = new Facilities();
                facilities.comparator = function(facility) {
                    return facility.get("name");
                }

                $('#facilityName', $container).val(selectedFacilityName);
                $('#facilityCode', $container).val(selectedFacilityCode);
                    
                var selectedDateRangeValue = $container.find("#select-date-range").val();
                this.calculateStartAndEndDates(selectedDateRangeValue, $container.find("#startDate"), $container.find("#endDate"));

                var autosearch = false;
                var currentPage = $(location).attr('hash');
                if (this.userSession.isLoggedIn()) {
                    var user = this.userSession.get('mhpuser');
                    if (typeof $('#facilityName', $container).val() === 'undefined' || $('#facilityName', $container).val().length === 0){
                            $('#facilityName', $container).val(user.facilityName)
                            $('#facilityCode', $container).val(user.vistaLocation);
                    }
                    if ($('#facilityName', $container).val() === user.facilityName && $('#facilityCode', $container).val() === user.vistaLocation) {
                        that.antibiogram = new Antibiogram(user.vistaLocation);
                        $("#main").attr('data-valid-facility',user.facilityName);
                        if(currentPage === '#antibiogram-search') {
                            $("#organismName", $container).removeAttr("disabled").focus();
                        } else if(currentPage === '#search-all') {
                            autosearch = true;
                        }
                    }
                    that.facilitySelectTriggered = true;
                } else if($("#main").attr('data-valid-facility') !== undefined && $("#main").attr('data-valid-facility') === $("#facilityName").val()){
                    that.antibiogram = new Antibiogram($('#facilityCode', $container).val());
                    if(currentPage === '#antibiogram-search') {
                        $("#organismName", $container).removeAttr("disabled").focus();
                    } else if(currentPage === '#search-all') {
                        autosearch = true;
                    }
                }

                var $content = $('#main').find(":jqmData(role='content')");
                $content.empty().append($container);

                if (!fromMainLoad) {
                    $content.trigger('create');
                }

                this.enableAutoComplete();

                if(autosearch){
                    this.checkInputFields();
                }
                return $container;
            },

            dateRangeSelected: function(){
                this.calculateStartAndEndDates($("#select-date-range").val(), $("#startDate"), $("#endDate"));
                this.checkInputFields();
            },
            calculateStartAndEndDates: function(selectedDateRange, $startDateContainer, $endDateContainer) {
                var start = new Date();
                start.setMonth(start.getMonth() - parseInt(selectedDateRange, 10));
                var endDate = $.datepicker.formatDate('mm/dd/yy', new Date()),
                    startDate = $.datepicker.formatDate('mm/dd/yy', start);
                $startDateContainer.val(startDate);
                $endDateContainer.val(endDate);
            },
            checkInputFields: function () {
                var that = this,
                    $content = $('#main').find(":jqmData(role='content')"),
                    facilityCode = $("#facilityCode", $content).val(),
                    facilityName = $("#facilityName", $content).val(),  
                    organismId = $("#organismId", $content).val(), 
                    startDate = $("#startDate", $content).val(),
                    endDate = $("#endDate", $content).val(),
                    objectType = $("#objectType", $content).val();

                //clear old data
                this.destroyTableIfThere();
                
                if (!(startDate && endDate)) {
                    that.showErrorMessage("Date range is missing");
                    return;
                }
                if (facilityCode){
                    if($('#organismName').is(":visible") && organismId && objectType == "Organism") {
                        this.displayAntibioticResults(facilityCode, organismId, startDate, endDate);
                    } else if (!$('#organismName').is(":visible") || objectType == "OrganismGroup") {
                        var searchId;
                        if (objectType == "OrganismGroup"){
                            searchId = organismId;
                        } else {
                            searchId = null;
                        }
                        this.displaySummaryResults(facilityCode, facilityName, searchId, startDate, endDate)
                    }
                }
            },
            displayAntibioticResults: function (facilityCode, organismId, startDate, endDate) {
                var that = this,
                		   restURL = resources.get("antibiogram-facility").get('href') + "/" + facilityCode + "/organism/" + organismId + "/antibiotic"; 
                
                $.getJSON(restURL, {"startDate":startDate,"endDate":endDate}, function( data ) {
                    
                    if(data.organism !== undefined){
                        // Add <thead> and <tbody> to the now-empty table.
                        $("#results").append("<table class='antibiotic-results'><thead><tr class='ui-header ui-bar-d'><th class='antibiotic'><div class='header'><span class='ui-icon  ui-icon-shadow'>&nbsp;</span>Antibiotic (# Isolates)</div></th><th class='percent'><div class='header'><span class='ui-icon ui-icon-shadow'>&nbsp;</span>Susceptibility %</div></th></tr></thead><tbody></tbody><table>");
                        $("#isolates-note").removeClass("hide");
                        // Add rows populated with the returned json.
                        var organisms = data.organism;
                        $.each(organisms, function(i,organism) {
                            $("#results tbody").append("<tr><td>" + organism.antibioticName + " (<span class='isolatesCount'>" + organism.testCount + "</span>)</td><td class='percent'>" + Math.floor(organism.ratio) + "</td></tr>");
                        });

                        if ($(window).width() > 760){
                            scrollHeight = that.getScrollHeight();
                        } else {
                            scrollHeight = "";
                        }

                        // Initialize dataTable
                        var oTable = $("#results table.antibiotic-results").dataTable({
                            "aaSorting": [[1,'desc']],
                            "sScrollY": scrollHeight,
                            "bScrollCollapse": true,
                            "bPaginate": false,
                            "bFilter": false,
                            "bJqueryUI": true,
                            "oLanguage": {
                                  "sInfo": "Showing _START_ to _END_ of _TOTAL_ results"
                            },
                            "sDom": '<"ui-grid-a table-heading"<"ui-block-a"i><"ui-block-b">><"H">t<"F">'
                        });
                        //low isolate indicator ANTIBIOTIC-143
                        $("#results .isolatesCount").each(function(){
                            var n = parseInt($(this).html(),10);
                            if (n < that.lowIsolateThreshold){
                                $(this).closest('tr').addClass('low-isolate');
                                $(this).append("*");
                            }
                        });
                    } else {
                        that.showErrorMessage("There were no Antibiotics to display for the Facility and Organism selected");
                    }
                });
            },
            displaySummaryResults: function (facilityCode, facilityName, searchId, startDate, endDate){
                var that = this,
                    pdfUrl,
                    generatedUrl,
                    dataVars;

                if(searchId === null){
                    // Facility/Complete view
                    pdfURL = resources.get("antibiogram-facility").get('href') + "/" + facilityCode + "/" + facilityName + "/report?startDate=" + startDate + "&endDate=" + endDate;
                	
                	$("#results").before('<a href="' + pdfURL + '" data-role="button" data-icon="star" data-theme="a" class="pdf-button" target="_blank">Download PDF</a>');
                    //necessary for page switching
                    $(".pdf-button").buttonMarkup();        
                    generatedUrl = that.antibiogram.get('antibiogram-facility-matrix').href;
                    dataVars = {"startDate":startDate,"endDate":endDate};
                } else {
                    // Search view (groups)
                    generatedUrl = that.antibiogram.get('antibiogram-facility-organism').href;
                    generatedUrl = generatedUrl + "/" + searchId + "/antibiotic";
                    //generatedUrl = generatedUrl + "/3/antibiotic"; //test data
                    dataVars = {"startDate":startDate,"endDate":endDate};
                    //dataVars = {"startDate":"01/01/2010","endDate":endDate}; //test data
                }

                //For Facility view, only show PDF button on smaller screens
                if($(window).width() > 760 || searchId !== null){
                    antibiogramMatrix = new AntibiogramMatrix();

                    antibiogramMatrix.fetch({
                        url: generatedUrl,
                        data: dataVars,
                        dataType: 'json',
                        success: function (collection) {
                            var maxH = 0,
                                scrollHeight = 0;
                            if(collection.length>0){
                                this.antibiogramSummaryView = new AntibiogramSummaryView({
                                    el: $('#results'),
                                    antibiogramMatrix: collection
                                });

                                //set header height based on tallest (widest 90deg) content
                                $("th .rotate").each(function(){
                                    var w = $(this).width();
                                    if (w > maxH) {
                                        maxH = w;
                                    }
                                });
                                maxH += 5;
                                $("table.complete-results th").css('height',maxH+"px");

                                if ($(window).width() > 760){
                                    scrollHeight = that.getScrollHeight();
                                } else {
                                    scrollHeight = "";
                                }

                                //datatables.js
                                var oTable = $('#results table').dataTable({
                                    "sScrollX": "100%",
                                    "sScrollY": scrollHeight,
                                    "bScrollCollapse": true,
                                    "bFilter": false,
                                    "bPaginate": false,
                                    "oLanguage": {
                                          "sInfo": "Showing _START_ to _END_ of _TOTAL_ results"
                                    },
                                    "sDom": '<"ui-grid-a table-heading"<"ui-block-a"i><"ui-block-b">>t'
                                });

                                //low isolate indicator ANTIBIOTIC-143
                                $("#results .isolatesCount").each(function(){
                                    var n = parseInt($(this).html(),10);
                                    if (n < that.lowIsolateThreshold){
                                        $(this).closest('tr').addClass('low-isolate');
                                        $(this).append("*");
                                    }
                                });

                                $("#isolates-note").removeClass("hide");

                                new FixedColumns( oTable, {
                                    "iLeftColumns": 2,
                                    "iLeftWidth": 200
                                });

                                //center the column headers like a BOSS
                                $("thead th").each(function(){
                                    var w = $(this).width();
                                    $(".dataTables_scrollHead .rotate").css('line-height',w+"px")
                                });
                            } else {
                                that.showErrorMessage("There is no data to display for the Facility selected");
                            }
                        },
                        statusCode: {
                            302 : function() {
                                loginRedirect();
                            },
                            500 : function() {
                                that.showErrorMessage('There was a problem getting information from the server. (antibiogramMatrix.fetch)');
                            }
                        }
                    });
                }
            },
            facilityNameModified: function (e) {
                
                var currentPage = $(location).attr('hash');
                //validates the facility from page to page without forcing the user to select if from the autocomplete every time.
                if($("#main").attr('data-valid-facility') !== $("#facilityName").val()){
                    $('#organismName').textinput('disable');
                    // Remove the table because it's no longer correct.
                    this.destroyTableIfThere();
                }
                if(currentPage === "#antibiogram-search"){
                    $('#organismName').val("");
                    $("#organismId").val("");
                    // Remove the table because it's no longer correct.
                    this.destroyTableIfThere();
                } else if ($("#facilityName").val()==="") {
                    $('#facilityCode').val("");
                }
            },
            organismNameModified: function(e) {
                if ($("#organismName").val()==="") {
                    $('#organismId').val("");
                    // Remove the table because it's no longer correct.
                    this.destroyTableIfThere();
                }
            },
            destroyTableIfThere: function () {
                $("#results").html("");
                $("#isolates-note").addClass("hide");
                $(".pdf-button").remove();
            },
            getScrollHeight: function() {
                //Determine height of correct sScrollY based on window size
                var scrollHeight = $(window).height()
                             - $("table th").outerHeight() //column headers
                             - $('#results').position().top //all UI above table
                             - $('#results .table-heading').outerHeight() //text above table
                             - $('#footer').outerHeight() //footer buttons
                             - $('p.note').outerHeight() //text below table
                             - 45; //padding at bottom
                return scrollHeight
            },

            events: {
                "change #select-date-range" : "dateRangeSelected",
                "change #facilityName" : "facilityNameModified",
                "change #organismName" : "organismNameModified"
            }
        });
    }
);