/**
 * @todo refactoring
 * @todo matrix view rewrite
 * @todo price view write
 */
var Matrix = Class.create({
    numberColumns: 10,
    initialize: function() {
        this.selectedAirlines = [];
        this.container = new Element("div", {id: "resultMatrix"}).hide();
        $('result_container').appendChild(this.container);
        var progressImageElement = new Element('img', {
            id : 'search_progress_image',
            src: '/i/search_indicator.gif'
        }).hide();
        $('result_owner').appendChild(progressImageElement);
    },
    show: function() {
        this.redraw();
        this.container.show();
        Page.getInstance().getForm().moveTo('result_container');
        $('flights_title').update($('resultHeaderSign').firstChild.nodeValue);
        ['page', 'l_col', 'new_column'].each(Element.hide);
        ['flights_result_header', 'result_container'].each(Element.show);
        if (!Page.getInstance().getFlights().getData().isFinished()) {
            $('search_progress_image').show();
        }
        if (typeof search123Class.getInstance() == 'object') {
            setTimeout(function(){
                search123Class.getInstance()._render();
            }, 100);
        }
        $('c_col').addClassName('wide_col');
    },
    hide: function() {
        try {
            var elements = ['result_container', 'flights_result_header', 'details_block'];
            elements.each(Element.hide);
        } catch (e) {
            dispatchException(e);
        }
        if (Browser.isIE && $('details_iframe')) {
            $('details_iframe').hide();
        }
        if (typeof search123Class.getInstance() == 'object') {
            setTimeout(function(){
                search123Class.getInstance()._render();
            }, 100);
        }
        $('c_col').removeClassName('wide_col');
        setTimeout(function() {
            Page.getInstance().getMatrix().clear();
        }, 500);
    },
    redraw: function() {
        try {
            if (Page.getInstance().getFlights().getData().isUpdated()) {
                this.clear();
                this.draw();
                this.insertPrivateJet();
            }
        } catch (e) {
            dispatchException(e);
        }
    },
    clear: function() {
        $('share').appendChild($('details_block'));
        $('details_iframe') && $('share').appendChild($('details_iframe'));
        this.container.update('');
    },
    createMatrix: function() {
        this.matrix = {};
        Page.getInstance().getFlights().getData().getAirlines().each(function() {
            var airline = arguments[1];
            this.matrix[airline.getCode()] = {};
            Page.getInstance().getFlights().getData().getVendors().each(function() {
                var airline = arguments[0];
                var vendor  = arguments[1];
                this.matrix[airline.getCode()][vendor.getCode()] = Math.random();
            }.bind(this, airline));
        }.bind(this));
    },
    draw: function() {
        var data = Page.getInstance().getFlights().getData();
        try {
            data.calculate();
        } catch (e) {
            dispatchException(e);
        }
        var vendors  = data.getVendors();
        var airlines = data.getAirlines();
        var prices   = data.getPrices();
        var matrixTable = elem('table', {cellSpacing: 0});
        this.container.appendChild(matrixTable);
        try {
            var theadElement   = elem('thead');
            matrixTable.appendChild(theadElement);
            var trSearchCriteria = elem('tr');
            var tdSearchCriteria = $(elem('td', {colSpan: 11, id: 'caption'}))
                                  .addClassName('bl_text');
            var criteriaBlock = $(elem('div', false, false, {textAlign: 'left'}))
                               .addClassName("cities");

            try {
                var carbonContainer = Page.getInstance().getFlights().carbon.getView().render();
                tdSearchCriteria.appendChild(carbonContainer);

                tdSearchCriteria.appendChild($(elem("div")).addClassName("currency_container")
                    .appendChild($(elem("div")).addClassName("currency_sign")
                        .update($("currency_sign").firstChild.nodeValue)).parentNode
                    .appendChild(document.createTextNode($("leadingAirlinesSign").firstChild.nodeValue)).parentNode);
            } catch (e) {
                dispatchException(e);
            }
            criteriaBlock.innerHTML = this.getCriteriaContainer();
            tdSearchCriteria.appendChild(criteriaBlock);
            trSearchCriteria.appendChild(tdSearchCriteria);
            theadElement.appendChild(trSearchCriteria);
        } catch (e) {
            dispatchException(e);
        }
        var tbodyElement = elem("tbody");
        matrixTable.appendChild(tbodyElement);
        var vendorsTRHeaderElement = elem("tr");        
        var airlinesColumnElement = new Element("td", {id: "airlinesColumnTd"});
        if (new RegExp("dubai").test(window.location.host)) {
            airlinesColumnElement.addClassName("airlinesColumnTdAlternate");            
        } else {
            airlinesColumnElement.addClassName("airlinesColumnTd");
        }
        /* WARNING Compare lines exists on line 187
        if (new RegExp("bizclass").test(window.location.host)) {
            var compareButtonElement = elem("img", {src: "/common/i/flights/bt.compare.gif", id: "compareButton"});
            Event.observe(compareButtonElement, "click", function() {
                if (typeof(this.comparePrices) != "undefined" && this.comparePrices.length > 1) {
                    var vars = $H({
                        prices: this.comparePrices.join(","),
                        departure: $("departureAirport").value,
                        destination: $("destinationAirport").value
                    });
                    window.open("/flights/?action=compare&" + vars.toQueryString());
                } else {
                    alert("Please choose prices first");
                }
            }.bindAsEventListener(this));
            airlinesColumnElement.appendChild(compareButtonElement);
        }*/
        airlinesColumnElement.appendChild(elem("br"));
        airlinesColumnElement.appendChild(document.createTextNode("Airlines"));
        vendorsTRHeaderElement.appendChild(airlinesColumnElement);
        var m = this.numberColumns;
        if (data.hasDirectVendors()) {
            var directVendorsHeaderTdElement = new Element("td").update("Airline Direct")
                                              .addClassName("vendorCell");
            vendorsTRHeaderElement.appendChild(directVendorsHeaderTdElement);
            m--;
        }
        for (var i = 0; i < m; i++) {
            var vendor = (typeof(vendors[i]) != "undefined") ? vendors[i] : false;
            if (vendor && vendor.isDirect()) {
                m++;
                continue;
            }
            var vendorHeaderTDElement = new Element("td").addClassName("vendorCell");
            if (vendor) {
                if (!vendor.isDirect()) {
                    vendorHeaderTDElement.appendChild(vendor.getView().render());
                    vendorsTRHeaderElement.appendChild(vendorHeaderTDElement);
                }
            } else {
                vendorHeaderTDElement.appendChild(document.createTextNode(" "));
                vendorsTRHeaderElement.appendChild(vendorHeaderTDElement);
             }
        }
        tbodyElement.appendChild(vendorsTRHeaderElement);
        var airlines = data.getAirlines();
        var prices   = data.getPrices();
        try {
            for (var i = 0, airlinesLength = airlines.length; i < airlinesLength; i++) {
                var airline = airlines[i];
                
                
                var pricesRowElement = $(elem("tr"));
                pricesRowElement.setAttribute("airline", airline.getCode());
                if (this.selectedAirlines.length > 0 && this.selectedAirlines.indexOf(airline.getCode()) != -1) {
                    pricesRowElement.addClassName("selected");
                }
                var airlineCellElement = $(elem("td")).addClassName("airlineCell");
                tbodyElement.appendChild(pricesRowElement);
                var innerTableElement = elem("table", {cellSpacing: 0, cellPadding: 0, width: "100%", border: 0}, {border: 0});
                var innerTbodyElement = elem("tbody");
                var innerTrElement    = elem("tr");
                //var checkboxCellElement    = $(elem("td")).addClassName("checkboxCell");
                var airlineLogoCellElement = $(elem("td")).addClassName("airlineLogoCell");
                airlineCellElement.appendChild(innerTableElement);
                innerTableElement.appendChild(innerTbodyElement);
                innerTbodyElement.appendChild(innerTrElement);
                //innerTrElement.appendChild(checkboxCellElement);
                innerTrElement.appendChild(airlineLogoCellElement);
                /* WARNING Compare lines exists on line 120
                if (new RegExp("bizclass").test(window.location.host)) {
                    var checkboxElement = elem("input", {type: "checkbox"});
                    Event.observe(checkboxElement, "click", this.onCheckboxClick.bind(this));
                    checkboxCellElement.appendChild(checkboxElement);
                }*/
                airlineLogoCellElement.appendChild(airline.getView().render());
                pricesRowElement.appendChild(airlineCellElement);
                var z = this.numberColumns;

                try {
                    if (data.hasDirectVendors()) {
                        var directVendor = false;
                        var matrixCell = new Element("td");
                        if ((directVendor = airline.getVendor()) != false) {
                            var directVendorPrice = directVendor.getPrice();
                            if (directVendorPrice) {
                                matrixCell.addClassName("result_cell");
                                matrixCell.appendChild(directVendorPrice.getView().render());
                                matrixCell.price = directVendorPrice;
                                matrixCell.getElementsBySelector('div.details').each(function(div) {
                                    Event.observe(div, "click", this.showPriceDetails.bindAsEventListener(this));
                                }.bind(this));
                            } else if (directVendor.isFinished()) {
                                matrixCell.innerHTML = "&nbsp;";
                                matrixCell.addClassName("nullResultCell");
                            }
                        } else {
                            matrixCell.innerHTML = "&nbsp;";
                            matrixCell.addClassName("nullResultCell");
                        }
                        pricesRowElement.appendChild(matrixCell);
                        z--;
                    }
                } catch (e) {
                    dispatchException(e);
                }
                for (var k = 0; k < z; k++) {
                    var vendor = (k in vendors) ? vendors[k] : false;
                    var cellReady = false;
                    if (vendor && vendor.isDirect()) {
                        z++;
                        continue;
                    }
                    try {
                        if (data.hasDirectVendors() && vendor.getLogo() && vendor.isDirect()) {
                            cellReady = true;
                            z++;
                        }
                    } catch (e) {
                        //dispatchException(e, vendor);
                    }
                    if (vendor && !cellReady) {
                        for (var j = 0, pricesLength = prices.length; j < pricesLength; j++) {
                            if (!(j in prices)) {
                                continue;
                            }
                            var price = prices[j];
                            try {
                                price.getAirline();
                                price.getVendor().getCode();
                            } catch (e) {
                                dispatchException(e);
                                continue;
                            }

                            try {
                                if (price.getAirline().getCode() != airline.getCode()) {
                                    continue;
                                }
                                if (price.getVendor().getCode() != vendor.getCode()) {
                                    continue;
                                }
                                var priceCellElement = new Element("td", {
                                                            id: price.getUniqueId(),
                                                            priceId: price.getId()})
                                                      .addClassName("result_cell");
                                priceCellElement.price = price;
                                priceCellElement.appendChild(price.getView().render());
    
                                pricesRowElement.appendChild(priceCellElement);

                                priceCellElement.getElementsBySelector('div.details').each(function(div) {
                                    Event.observe(div, "click", this.showPriceDetails.bindAsEventListener(this));
                                }.bind(this));

                                cellReady = true;
                                break;
                            } catch (e) {
                                dispatchException(e);
                            }
                        }
                    }
                    if (!cellReady) {
                        
                        var skip = false;
                        if (vendor && !vendor.isDirect() && !data.directVendorExistsForAirline(airline)) {
                            skip = true;
                        }
                        var nullResultCellElement = new Element("td").addClassName("nullResultCell");
                        nullResultCellElement.innerHTML = "&nbsp;";
                        if (k > 10) {
                            nullResultCellElement.addClassName("lastRowCells");
                        }
                        pricesRowElement.appendChild(nullResultCellElement);

                        if (vendor && !vendor.isFinished() && skip) {
                            nullResultCellElement.setAttribute("cross_bg", nullResultCellElement.style.backgroundImage);
                            nullResultCellElement.style.backgroundImage = "none";
                        }
                    }
                }
            }
        } catch (e) {
            dispatchException(e);
        }

        try {
            $A($('resultMatrix').getElementsByClassName('selected')).each(function(element) {
                element.firstChild.firstChild.setAttribute("checked", "checked");
            });
        } catch (e) {
            dispatchException(e);
        }
        try {
            if ($("details_block").parentNode.id == "share") {
                $("resultMatrix").appendChild($("details_block"));
                if (Browser.isIE) {
                    $("resultMatrix").appendChild($("details_iframe"));
                }
            }
        } catch(e) {
            dispatchException(e);
        }
        PrimaryLayout.getInstance().renderBottomLinks();
    },
    onCheckboxClick: function(event) {
        var element = Event.element(event);
        var trElement = $(element);
        while (trElement = trElement.parentNode) {
            if (trElement.getAttribute("airline")) {
                break;
            }
        }
        if (element.checked == true) {
            if (! trElement.hasClassName("selected")) {
                trElement.addClassName("selected");
                this.selectedAirlines.push(trElement.getAttribute("airline"));
            }
        } else if (trElement.hasClassName("selected")) {
                trElement.removeClassName("selected");
                this.selectedAirlines = this.selectedAirlines.without(trElement.getAttribute("airline"));
        }
        if (this.selectedAirlines.length >= 2) {
            if ($("compareButton").getOpacity() == 1) {
                Effect.Pulsate("compareButton");
            }
        }
        this.setPricesForComparing();
    },
    setPricesForComparing: function() {
        this.comparePrices = [];
        $A($("resultMatrix").getElementsByClassName("selected")).each(function(trElement) {
            if (trElement.childNodes.length == 0) {
                return;
            }
            $A(trElement.childNodes).each(function(tdElement) {
                tdElement.getElementsBySelector('div.bestFare').each(function() {
                    this.comparePrices.push(tdElement.getAttribute("priceId"));
                }.bind(this));
                tdElement.getElementsBySelector('div.bestPrice').each(function() {
                    this.comparePrices.push(tdElement.getAttribute("priceId"));
                }.bind(this));
            }.bind(this));
        }.bind(this));
    },
    finishSearching: function() {
        $("search_progress_image").hide();
                
        $A($("resultMatrix").select(".nullResultCell")).each(function(el) {
            if(el.style.backgroundImage == "none") {
               el.style.backgroundImage = el.getAttribute("cross_bg");
            }
        });
        
        $A($$('#resultMatrix tr[airline]').findAll(
            function(element,index) {
            
                var hasDirectVendor = false;
                hasDirectVendor = Page.getInstance().getFlights().getData().getAirlines()[index].getVendor();

                return element.getElementsBySelector('td[priceid]').length == 0 && !hasDirectVendor;
            }
        )).each( 
            function(element) {
                $(element).remove();
            }
        );        
    },
    hidePriceDetails: function() {
        Effect.Fade("details_block");
        if (Browser.isIE && $("details_iframe")) {
            $("details_iframe").remove();
        }
    },
    showPriceDetails: function(event) {
        var sourceElement = Event.element(event);
        if (sourceElement.nodeName.toLowerCase() == "a") {
            return;
        }
        if (sourceElement.nodeName.toLowerCase() != "td") {
            while (sourceElement = sourceElement.parentNode) {
                if (sourceElement.nodeName.toLowerCase() == "td") {
                    break;
                }
            }
        }
        var xPosition = sourceElement.offsetLeft + sourceElement.clientWidth  - 9;
        var yPosition = sourceElement.offsetTop  + sourceElement.clientHeight - 15;
        if (Browser.isIE) {
            if (!$("details_iframe")) {
                var iframeElement = $(elem("iframe", {
                    id:"details_iframe",
                    frameBorder: "0"
                })).setStyle({top: (yPosition + 15), left: xPosition});
                $("resultMatrix").appendChild(iframeElement);
            } else {
                $("details_iframe").setStyle({
                    top: (yPosition + 15) + "px",
                    left: (xPosition) + "px"
                });
                $("resultMatrix").appendChild($("details_iframe"));
            }
        }
        if (($("details_block").style.display == "none")) {
            Effect.Appear("details_block", {duration: 0.5});
        }
        $("details_block").style.top  = yPosition + "px";
        $("details_block").style.left = xPosition + "px";
        this.fillDetails(sourceElement);
    },
    fillDetails: function (priceCell) {
        var price = priceCell.price;
        var data = Page.getInstance().getFlights().getData();
        if (price.detailsExists()) {
            var outboundDetails = price.getDetails("outbound");
            var detailsContentNodes = this.getContentNodes(outboundDetails);
            var inboundDetails = price.getDetails("inbound");
            if (! inboundDetails) {
                var inboundDetails = {
                    stops: 'n/a',
                    arrivingTime: 'n/a',
                    departingTime: 'n/a',
                    airline: outboundDetails.airline,
                    duration: 'n/a',
                    airport: data.getData('destination'),
                    date: data.getData("datesString").split(" - ")[1]
                };
            }

            if ($("tripTypeR").checked == true) {
                detailsContentNodes = detailsContentNodes.concat(this.getContentNodes(inboundDetails, true));
            }

            var textElement = new Element("div").addClassName("text");
            var cElement    = elem("div", {id: "c"}).appendChild(textElement)
                            .parentNode;

            detailsContentNodes.each(function() {
                var textElement = arguments[0];
                textElement.appendChild(arguments[1]);
            }.bind(this, textElement));

            if ($("tripTypeR").checked == false) {
                cElement.style.height = "85px";
                $("details_block").style.height = "90px";
                if (Browser.isIE) {
                    $("details_iframe").style.height = "75px";
                }
            }
            var closeElement = new Element("div")
                .setStyle({textAlign: "right", position: "relative", zIndex: 100})
                .addClassName("close")
                .appendChild(
                    new Element("img", {
                        src: "/common/i/flights/details_close.gif",
                        id: "close_details"
                    })
                ).parentNode;

            cElement.appendChild(closeElement);

            $("details_block").update();
            $("details_block").appendChild(cElement);
            $("details_block").appendChild(elem("DIV", {id: "bottom"}));

            Event.observe("close_details", "click", this.hidePriceDetails.bindAsEventListener(this));
        }
    },
    getContentNodes: function(details, inbound) {
        var nodes = [];
        nodes.push(elem("h5"));
        nodes[0].appendChild(elem("b", false, false, inbound ? "Return" : "Depart"));
        nodes[0].appendChild(document.createTextNode(" - " + details.date));
        nodes.push(elem("span", {className: "gray"}, false, "From"));
        nodes.push(document.createTextNode(" " + details.airport));
        nodes.push(elem("br"));
        nodes.push(elem("span", {className: "gray"}, false, "Departs:"));
        nodes.push(document.createTextNode(" " + details.departingTime + " "));
        nodes.push(elem("span", {className: "gray"}, false, "Arrives:"));
        nodes.push(document.createTextNode(" " + details.arrivingTime + " "));
        nodes.push(elem("br"));
        nodes.push(elem("span", {className: "gray"}, false, "Duration:"));
        nodes.push(document.createTextNode(" " + details.duration + " "));
        nodes.push(elem("span", {className: "gray"}, false, "Stops:"));
        nodes.push(document.createTextNode(" " + details.stops + " "));
        nodes.push(elem("br"));
        nodes.push(elem("span", {className: "gray"}, false, "Airline:"));
        nodes.push(document.createTextNode(" " + details.airline));
        return nodes;
    },
    insertPrivateJet: function() {
        var hostName = window.location.hostname;
        if (hostName.match('bizclass')) {
            var dimensions = $$('#result_matrix table')[0].getDimensions();
            var data = page.getFlights().getData();
            content.locations   = data.getData("locationsString")
                                ? data.getData("locationsString").split(' - ')
                                : false;
            var res = content.locations[0].match(new RegExp("([^\(]+)[\(]([^\)]+)[\)](.+)","i"));
            content.departureCode   = res[2];
            var res = content.locations[1].match(new RegExp("([^\(]+)[\(]([^\)]+)[\)](.+)","i"));
            content.destinationCode = res[2];
            var tablePrivateJetElement    = elem("table", 
                             {cellspacing: 0, cellpadding: 0}, 
                             {width: '633px', height: '70px', border: '1px solid #ebead8'
                             }, false);
            var tbodyPrivateJetElement = elem("tbody");
            var trPrivateJetElement = elem("tr", {valign: 'middle'});
            var tdPrivateJetElement = elem("td", {align: 'center'}, {padding: '10px', border: 0, textAlign: 'center'});
            var anchorPrivateJetElement = elem("a", 
                                       {href: "/private-jet/?destination=" + content.destinationCode + "&departure=" + content.departureCode
                                       }, {
                                           fontWeight: 'bold', 
                                           backgroundColor: '#ebead8', 
                                           border: '1px solid #d6d5bd',
                                           display: 'block',
                                           padding: '5px',
                                           textDecoration: 'none'
                                       },
                                           "Private Jets available between " +
                                           content.locations[0] + " and " + content.locations[1] + "."  
                                       );
            anchorPrivateJetElement.appendChild(elem("br"));
            anchorPrivateJetElement.appendChild(elem("br")); 
            anchorPrivateJetElement.appendChild(document.createTextNode("For more information please click here."));
            tdPrivateJetElement.appendChild(anchorPrivateJetElement);
            trPrivateJetElement.appendChild(tdPrivateJetElement);
            tbodyPrivateJetElement.appendChild(trPrivateJetElement);
            tablePrivateJetElement.appendChild(tbodyPrivateJetElement);
            $("result_matrix").appendChild(tablePrivateJetElement);
        }
    },
    getCriteriaContainer: function() {
        var data = Page.getInstance().getFlights().getData();
        var content = {};
        var criteria = data.getData("criteria");

        content.sign        = $("leadingAirlinesSign").firstChild.nodeValue;
        content.locations   = data.getData("locationsString")
                            ? data.getData("locationsString").split(' - ')
                            : false;

        content.departure   = criteria.departure.airport
                            + " [" + criteria.departure.code + "], "
                            + criteria.departure.country;
        content.destination = criteria.destination.airport
                            + " [" + criteria.destination.code + "], "
                            + criteria.destination.country;
        content.dates       = data.getData("datesString")
                            ? data.getData("datesString").split(' - ')
                            : false;
        content.departDate  = content.dates[0];
        content.returnDate  = content.dates[1];
        content.passengers  = Page.getInstance().getFlights().getData().criteria.passengers;

        content.iata        = Page.getInstance().getForm().getIATA("destinationAirport");

        var template = new Template("<b>Depart:</b> #{departure}<br /><b>Depart date:</b> #{departDate}<br /><b>Destination:</b> #{destination}<br /> " + (($("tripTypeR").checked == true) ? "<b>Return date:</b> #{returnDate}<br />" : "") + "<b>Passengers:</b> #{passengers}<br />");
        return template.evaluate(content);
    }
});