﻿var Panel = Class.create({
    initialize: function(passportReference, tridionPanelId) {
        this.postBody = [];
        this.passportReference = passportReference;
        this.data = null;
        this.components = null;
        this.tridionPanelId = tridionPanelId;
        this.panelHTML = $$('[id=' + this.tridionPanelId + ']')[0];


    },
    limitDigits: function(el) {
        jsHelper.permitOnlyDigits(el);
        jsHelper.limitSize(el, 2);
    },
    applyComponentsVisibility: function() {
        this.components.each(function(item) {
            if (item.value == 'False') {
                var comp = this.panelHTML.select('[id=' + item.id + ']')[0];
                if (comp != undefined) {
                    var currentVisibility = comp.getStyle('display');
                    if (currentVisibility == 'inline') {
                        comp.setStyle({ 'display': 'none' });
                    }
                    else {
                        comp.setStyle({ 'display': 'inline' });
                    }
                }
            }
        } .bind(this));
    },
    __validateSubmit: function() {
        var formData = this.panelHTML.select('form')[0].serialize(true);
        if (this._validateInputData(formData)) {
            this.panelHTML.select('[name=inputAddToCart]').each(function(el) {
                el.removeClassName('disabledButton');
            });
        }
        else {
            this.panelHTML.select('[name=inputAddToCart]').each(function(el) {
                el.addClassName('disabledButton');
            });
        }
    },
    __setup2SpanPrices: function(price1, price2, el1, el2, elTotal, iq1, iq2) {
        var stringPrice1 = '$ ' + parseFloat(price1).toFixed(2);
        var stringPrice2 = '$ ' + parseFloat(price2).toFixed(2);
        el1.update(stringPrice1);
        el2.update(stringPrice2);

        var calculateTotalPrice = function() {
            var q1 = jsHelper.toInt($F(iq1));
            var q2 = jsHelper.toInt($F(iq2));
            var totalPrice = q1 * parseFloat(price1) + q2 * parseFloat(price2);
            if (totalPrice == 0) {
                elTotal.update('-');
            }
            else {
                elTotal.update('$ ' + totalPrice.toFixed(2));
            }
        } .bind(this);

        calculateTotalPrice();

        [iq1, iq2].each(function(iq) {
            iq.observe('keyup', function(event) {
                calculateTotalPrice();
            } .bind(this));
        } .bind(this));

    },
    __setup1SpanPrice: function(price1, el1, elTotal, iq1) {
        var stringPrice1 = '$ ' + parseFloat(price1).toFixed(2);
        el1.update(stringPrice1);


        iq1.observe('keyup', function(event) {
            var q1 = jsHelper.toInt($F(iq1));
            var totalPrice = q1 * parseFloat(price1);
            if (totalPrice == 0) {
                elTotal.update('-');
            }
            else {
                elTotal.update('$ ' + totalPrice.toFixed(2));
            }

        } .bind(this));


    },
    __setupAddToCart: function() {

        this.panelHTML.select('[name=inputAddToCart]').each(function(el) {
            el.onClickWithContext(this, function() {

                var data = this.panelHTML.select('form')[0].serialize(true);

                if (data.inputAdultQuantity != undefined) { data.inputAdultQuantity = jsHelper.toInt(data.inputAdultQuantity); }
                if (data.inputChildQuantity != undefined) { data.inputChildQuantity = jsHelper.toInt(data.inputChildQuantity); }
                if (data.inputAdultChildQuantity != undefined) { data.inputAdultChildQuantity = jsHelper.toInt(data.inputAdultChildQuantity); }
                if (this._validateInputData(data)) {
                    this._formatDataAndSend(data);
                    var addAnoherItem = data['hdnShowAddOtherItem'];
                    addAnoherItem = addAnoherItem == 'True' ? true : false;
                    if (addAnoherItem) {
                        this.passportReference.fadeManager.fadeSpecificArea();
                        var popup = $$('.addAnotherItem')[0];
                        $$('body')[0].insert({ top: popup });
                        var panelContent = this.panelHTML;
                        var passportPosition = panelContent.cumulativeOffset();

                        var left = parseInt((panelContent.getWidth() - 200) / 2);

                        popup.setStyle({
                            zIndex: 59,
                            'left': 40 + '%',
                            top: 40 + '%'
                        });
                        popup.show();
                    }
                    else {
                        this.passportReference.goNextPanel(this.passportReference.getSelectedPanel());
                    }

                }
            });
        } .bind(this));
    },
    __setupInput: function(el) {
        jsHelper.permitOnlyDigits(el);
        jsHelper.limitSize(el, 2);
        el.observe('keyup', function(event) {
            this.__validateSubmit();
            this.saveValueChanged('text/' + this.classPrefix + el.readAttribute('name'), $F(el));
        } .bind(this));
    },
    __setupStaticCalendar: function(dataCollection, priceMode, calendarEl, inputEl, radioName, spanTicketEl, spanDateEl, spanPriceEl, spanTotalPriceEl) {

        this.calendar = new NGCalendar(calendarEl, null, {
            visible: true,
            idPrefix: this.classPrefix + '-',
            daysText: 'char',
            allowWeekendSelection: true
        });
        this.__setupStaticCalendar_disable(calendarEl);

        this.panelHTML.select('[name=' + radioName + ']').each(function(inputRadio) {
            inputRadio.onClickWithContext(this, function(event) {
                this.__setupStaticCalendar_enable(calendarEl);
                var radioValue = event.findElement().readAttribute('value');
                var dataIndex = radioValue.split('|')[0];
                var ticketName = radioValue.split('|')[1];
                spanTicketEl.update(ticketName);
                this.__setupStaticCalendarWithNoTicket(dataCollection[dataIndex].Edj, true, calendarEl, inputEl, spanDateEl, spanPriceEl, spanTotalPriceEl);
                var formData = this.panelHTML.select('form')[0].serialize(true);
                this.saveValueChanged('radioWithCalendar/' + this.classPrefix + radioName, formData[radioName]);
            } .bind(this));
        } .bind(this));


    },
    __setupStaticCalendar_disable: function(calendarEl) {
        this.calendar.options.allowSelection = false;
        this.calendar.populateCalendar();
        calendarEl.addClassName('disabledCalendar');
    },
    __setupStaticCalendar_enable: function(calendarEl) {
        this.calendar.options.allowSelection = true;
        this.calendar.populateCalendar();
        calendarEl.removeClassName('disabledCalendar');
    },
    __setupStaticCalendarWithNoTicket: function(dataCollection, priceMode, calendarEl, inputEl, spanDateEl, spanPriceEl, spanTotalPriceEl) {
        var eventData = $H();
        var priceCollection = this.__getPriceCollection(dataCollection);
        dataCollection.each(function(item) {
            var index = jsHelper.formatDate(new Date().fromString(item.De), 'Y-m');
            if (eventData.get(index) == undefined) {
                eventData.set(index, []);
            }
            var current = eventData.get(index);
            current.push(item);
        });

        if (this.previousDate == undefined) {
            this.calendar = new NGCalendar(calendarEl, null, {
                visible: true,
                idPrefix: this.classPrefix + '-',
                daysText: 'char',
                allowWeekendSelection: true,
                onSelect: this.__setupStaticCalendarWithNoTicket_ShowDetails.bind(this, eventData, inputEl, spanDateEl, spanPriceEl, spanTotalPriceEl),
                onCalendarLoad: this.__setupStaticCalendar_Paint.bind(this, eventData, priceCollection)
            });
            this.calendar.populateCalendar();
        }
        else {
            this.calendar = new NGCalendar(calendarEl, null, {
                visible: true,
                idPrefix: this.classPrefix + '-',
                daysText: 'char',
                allowWeekendSelection: true,
                onSelect: this.__setupStaticCalendarWithNoTicket_ShowDetails.bind(this, eventData, inputEl, spanDateEl, spanPriceEl, spanTotalPriceEl),
                onCalendarLoad: this.__setupStaticCalendar_Paint.bind(this, eventData, priceCollection)
            });
            this.calendar.date = this.previousDate;
            this.calendar.updateHeader();
            this.calendar.populateCalendar();
        }
        this.__setupStaticCalendar_Paint(eventData, priceCollection);
        this.__setupStaticCalendar_Footer(priceCollection, priceMode, calendarEl);
        inputEl.observe('keyup', function(event) {
            this.__setupStaticCalendarWithNoTicket_ShowDetails(eventData, inputEl, spanDateEl, spanPriceEl, spanTotalPriceEl);
        } .bind(this));
    },
    __setupStaticCalendar_Footer: function(priceCollection, priceMode, calendarEl) {
        var calendarFooterEl = this.panelHTML.select('.calendarFooter')[0];
        if (calendarFooterEl == undefined) {
            calendarFooterEl = new Element('div');
            calendarFooterEl.addClassName('calendarFooter');
            calendarEl.insert({
                after: calendarFooterEl
            });
        }
        var options = '';
        if (priceMode) {
            var i = 1;
            priceCollection.each(function(value) {
                var price = '$' + value.toFixed(2);
                options += '<div style="margin-left: 10px; display: inline;" class="calendarSelected' + i + '">&#160; &#160; &#160;</div> <span class="footerPrice">' + price + '</span>';
                i++;
            } .bind(this));
        }
        else {
            if (priceCollection.size() > 0) {
                options += '<div style="margin-left: 10px; display: inline;" class="calendarSelected1">&#160; &#160; &#160;</div> <span class="footerPrice">Available</span>';
            }
            options += '<div style="margin-left: 10px; display: inline;" class="calendarSelected0">&#160; &#160; &#160;</div> <span class="footerPrice">Not Available</span>';
        }
        var finalHtml = '<div style="text-align: center; margin-top: 6px;">' + options + '</div>';
        calendarFooterEl.update(finalHtml);
    },
    __setupStaticCalendar_Paint: function(eventData, priceCollection) {
        if (this.calendar != undefined) {
            this.previousDate = this.calendar.date;
            var index = jsHelper.formatDate(this.calendar.date, 'Y-m');
            var current = eventData.get(index);
            if (current != undefined) {
                current.each(function(item) {
                    var dateObject = new Date().fromString(item.De);
                    var cellId = this.classPrefix + '-date-' + (dateObject.getMonth() + 1) + '-' + dateObject.getDate() + '-' + dateObject.getFullYear();
                    var cell = this.panelHTML.select('[id=' + cellId + ']')[0];
                    var priceFormatted = parseFloat(item.Pri);
                    if (cell != undefined) {
                        cell.addClassName('calendarSelected' + (priceCollection.indexOf(priceFormatted) + 1));
                    }
                } .bind(this));
            }

            if (this.previousSelectedDate != undefined) {
                var dateObject = this.previousSelectedDate;
                var cellId = this.classPrefix + '-date-' + (dateObject.getMonth() + 1) + '-' + dateObject.getDate() + '-' + dateObject.getFullYear();
                var cell = this.panelHTML.select('[id=' + cellId + ']')[0];
                if (cell != undefined) {
                    cell.addClassName('ng-selected-day');
                }
            }
        }
    },
    __setupStaticCalendarWithNoTicket_ShowDetails: function(eventData, inputEl, spanDateEl, spanPriceEl, spanTotalPriceEl) {
        if (this.calendar != undefined) {
            var selectedDate = this.calendar.options.selectedDate;
            var quantity = parseInt($F(inputEl));
            this.previousSelectedDate = selectedDate;
            if (selectedDate != null) {
                var index = jsHelper.formatDate(this.calendar.date, 'Y-m');
                var current = eventData.get(index);
                if (current != undefined) {
                    var item = this.__getItemByDate(current, jsHelper.formatDate(selectedDate, 'm/d/Y'));
                    this.eventItemSelected = item;
                    spanDateEl.update(jsHelper.formatDate(selectedDate, 'F d, Y'));
                    if (item != null) {
                        var totalCost = quantity * parseFloat(item.Pri);
                        spanPriceEl.update('$' + parseFloat(item.Pri).toFixed(2));
                        if (totalCost > 0) {
                            spanTotalPriceEl.update('$' + totalCost.toFixed(2));
                        }
                        else {
                            spanTotalPriceEl.update('-');
                            spanPriceEl.update('-');
                        }
                    }
                    else {
                        spanDateEl.update('-');
                        spanPriceEl.update('-');
                        spanTotalPriceEl.update('-');
                        this.calendar.options.selectedDate = null;

                        this.calendar.updateHeader();
                        this.calendar.populateCalendar();

                        var cellId = this.classPrefix + '-date-' + (selectedDate.getMonth() + 1) + '-' + selectedDate.getDate() + '-' + selectedDate.getFullYear();
                        var cell = this.panelHTML.select('[id=' + cellId + ']')[0];
                        if (cell != undefined) {
                            cell.removeClassName('ng-selected-day');
                        }

                    }
                    this.saveValueChanged('calendar/' + this.classPrefix + 'calendar', jsHelper.formatDate(selectedDate, 'm/d/Y'));
                }
                else {
                    spanPriceEl.update('-');
                    spanTotalPriceEl.update('-');
                }
            }
            this.__validateSubmit();
        }
    },
    __getPriceCollection: function(dataCollection) {
        var priceCollection = [];
        dataCollection.each(function(item) {
            var priceFormatted = parseFloat(item.Pri);
            if (priceCollection.indexOf(priceFormatted) == -1) {
                priceCollection.push(priceFormatted);
            }
        });
        priceCollection = priceCollection.sort(function(a, b) {
            return a - b;
        });
        return priceCollection;
    },
    __getItemByDate: function(dataCollection, dateString) {
        var itemFound = null;
        dataCollection.each(function(item) {
            if (item.De == dateString) {
                itemFound = item;
            }
        });
        return itemFound;
    },
    __generateRowsFor2PricesWithCheck: function(setIdentifier, inputName, dataCollection, el, input1, input2) {
        var rowTemplate = new Template('<tr class="noBottomBorder"><td><input type="radio" name="' + inputName + '" value="#{productID1}|#{productID2}|#{variantID1}|#{variantID2}|#{catalog1}|#{catalog2}|#{CoPid}|#{CoPvid}" /> <a href="javascript:void(0);" id="popup_#{popupKey}">#{description}</a> #{comTicket}</td><td>#{stringPrice1}</td><td>#{stringPrice2}</td><td class="' + setIdentifier + 'tp">#{stringTotalPrice}</td></tr><tr class="subProduct"><td colspan="4" class="chkOption"><input name="subProduct" type="checkbox" value="#{subProductID1}|#{subProductID2}|#{subVariantID1}|#{subVariantID2}|#{subCatalog1}|#{subCatalog2}|#{CoPid}|#{CoPvid}" /> #{subDescription}</td></tr>');
        var html = '';
        var hasComTicket = false;
        dataCollection.each(function(pair) {
            html += rowTemplate.evaluate(pair.value);
            if (!hasComTicket && pair.value.isCo == 'True') {
                hasComTicket = true;
            }
        });
        el.update(html);

        //show commemorative ticket message if at least one ticket has it
        var multiDay_Msg = this.panelHTML.select('[id=multiDay_Msg]')[0];
        if (multiDay_Msg != null && hasComTicket) {
            multiDay_Msg.show();
        }

        this.__generateTotalPrice2Prices(setIdentifier, dataCollection, input1, input2);

        [input1, input2].each(function(input) {
            input.observe('keyup', function(event) {
                this.__generateTotalPrice2Prices(setIdentifier, dataCollection, input1, input2);
            } .bind(this));
        } .bind(this));

        el.select('a').each(function(aEl) {
            aEl.onClickWithContext(this, function(event) {

                var aClass = aEl.readAttribute('id');
                if (aClass.startsWith('popup')) {
                    var splitted = aClass.split('_');
                    var parkNumber = splitted[1];
                    var days = splitted[2];
                    var item = null;
                    var popup = $('DescriptionTicket');
                    var left = parseInt((800 - popup.getWidth()) / 2);
                    if (splitted.size() == 3) {
                        item = this.__getFilteredItemByParkAndDay(dataCollection, parkNumber, days);
                    }
                    else {
                        item = this.__getFilteredItemByKey(dataCollection, splitted[1]);
                    }
                    var description = popup.select('.description')[0];
                    description.update(item.descriptionTicket1);
                    popup.show();
                    popup.setStyle({ 'left': left + 'px' });

                }
            });
        } .bind(this));

        el.select('input[type=radio]').each(function(inputRadio) {
            inputRadio.onClickWithContext(this, function() {
                var inputCheck = inputRadio.up(1).next(0).select('input[type=checkbox]')[0];
                var currentState = inputCheck.checked;
                this.__removeHighlightRow();
                this.__removeChecks();
                inputCheck.checked = currentState;
                inputRadio.up(1).addClassName('selectedTr');
                inputRadio.up(1).next(0).addClassName('selectedTr');
                var formData = this.panelHTML.select('form')[0].serialize(true);
                var radioValue = formData[inputName];
                this.saveValueChanged('radio/' + this.classPrefix + inputName, radioValue);
                this.__validateSubmit();
            });
        } .bind(this));

        el.select('input[type=checkbox]').each(function(inputCheck) {
            inputCheck.onClickWithContext(this, function() {
                var currentState = inputCheck.checked;
                //show flexpay message
                if (currentState) {
                    var FlexPayMessage = this.panelHTML.select('[id=FlexPayMessage]')[0];
                    if (FlexPayMessage != null) {
                        FlexPayMessage.show();
                    }
                }
                else {
                    var FlexPayMessage = this.panelHTML.select('[id=FlexPayMessage]')[0];
                    if (FlexPayMessage != null) {
                        FlexPayMessage.hide();
                    }
                }
                this.__removeHighlightRow();
                this.__removeChecks();
                inputCheck.checked = currentState;
                inputCheck.up(1).addClassName('selectedTr');
                inputCheck.up(1).previous(0).addClassName('selectedTr');
                var radio = inputCheck.up(1).previous(0).select('input[type=radio]')[0];
                radio.checked = true;
                var formData = this.panelHTML.select('form')[0].serialize(true);
                var checkValue = formData['subProduct'];
                var radioValue = formData[inputName];
                if (checkValue == undefined) {
                    checkValue = '';
                }
                this.saveValueChanged('radio/' + this.classPrefix + inputName, radioValue);
                this.saveValueChanged('checkbox/' + this.classPrefix + 'subProduct', checkValue);
                this.__validateSubmit();
            });
        } .bind(this));
    },
    __generateRowsFor2Prices: function(setIdentifier, inputName, dataCollection, el, input1, input2) {
        var rowTemplate = new Template('<tr><td><input type="radio" name="' + inputName + '" value="#{productID1}|#{productID2}|#{variantID1}|#{variantID2}|#{catalog1}|#{catalog2}|#{CoPid}|#{CoPvid}" /> <a href="javascript:void(0);" id="popup_#{popupKey}" class="popup_#{popupKey}">#{description}</a> #{comTicket}</td><td>#{stringPrice1}</td><td>#{stringPrice2}</td><td class="' + setIdentifier + 'tp">#{stringTotalPrice}</td></tr>');
        var html = '';
        var hasComTicket = false;
        dataCollection.each(function(pair) {
            html += rowTemplate.evaluate(pair.value);
            if (!hasComTicket && pair.value.isCo == 'True') {
                hasComTicket = true;
            }
        });
        el.update(html);

        //show commemorative ticket message if at least one ticket has it
        var multiDay_Msg = this.panelHTML.select('[id=multiDay_Msg]')[0];
        if (multiDay_Msg != null && hasComTicket) {
            multiDay_Msg.show();
        }

        this.__generateTotalPrice2Prices(setIdentifier, dataCollection, input1, input2);

        [input1, input2].each(function(input) {
            input.observe('keyup', function(event) {
                this.__generateTotalPrice2Prices(setIdentifier, dataCollection, input1, input2);
            } .bind(this));
        } .bind(this));

        el.select('a').each(function(aEl) {
            aEl.observe('click', function(event) {
                var aEl = event.findElement();
                var aClass = aEl.readAttribute('id');
                if (aClass.startsWith('popup')) {
                    var splitted = aClass.split('_');
                    var parkNumber = splitted[1];
                    var days = splitted[2];
                    var item = null;
                    var popup = $('DescriptionTicket');
                    var left = parseInt((800 - popup.getWidth()) / 2);
                    if (splitted.size() == 3) {
                        item = this.__getFilteredItemByParkAndDay(dataCollection, parkNumber, days);
                    }
                    else {
                        item = this.__getFilteredItemByKey(dataCollection, splitted[1]);
                    }
                    var description = popup.select('.description')[0];
                    description.update(item.descriptionTicket1);
                    popup.show();
                    popup.setStyle({ 'left': left + 'px' });

                }
            } .bind(this));
        } .bind(this));

        el.select('input[type=radio]').each(function(inputRadio) {
            inputRadio.onClickWithContext(this, function() {
                this.__validateSubmit();
                this.__removeHighlightRow();
                this.__removeChecks();
                inputRadio.up(1).addClassName('selectedTr');
                var formData = this.panelHTML.select('form')[0].serialize(true);
                this.saveValueChanged('radio/' + this.classPrefix + inputName, formData[inputName]);
                this.saveValueChanged('checkbox/' + this.classPrefix + 'subProduct', '');
            });
        } .bind(this));
    },
    __generateRowsFor1Price: function(setIdentifier, inputName, dataCollection, el, input1) {
        var rowTemplate = new Template('<tr><td><input type="radio" name="' + inputName + '" value="#{productID1}|#{variantID1}|#{catalog1}" /> <a href="javascript:void(0);" id="popup_#{popupKey}">#{description}</a></td><td>#{stringPrice1}</td><td class="' + setIdentifier + 'tp">#{stringTotalPrice}</td></tr>');
        var html = '';
        dataCollection.each(function(pair) {
            html += rowTemplate.evaluate(pair.value);
        });
        el.update(html);
        this.__generateTotalPrice1Price(setIdentifier, dataCollection, input1);

        [input1].each(function(input) {
            input.observe('keyup', function(event) {
                this.__generateTotalPrice1Price(setIdentifier, dataCollection, input1);
            } .bind(this));
        } .bind(this));

        el.select('a').each(function(aEl) {
            aEl.onClickWithContext(this, function(event) {

                var aClass = aEl.readAttribute('id');
                if (aClass.startsWith('popup')) {
                    var splitted = aClass.split('_');
                    var key = splitted[1];

                    var popup = $('DescriptionTicket');
                    var left = parseInt((800 - popup.getWidth()) / 2);
                    var item = this.__getFilteredItemByKey(dataCollection, key);
                    var description = popup.select('.description')[0];
                    description.update(item.descriptionTicket1);
                    popup.show();
                    popup.setStyle({ 'left': left + 'px' });

                }
            });
        } .bind(this));

        el.select('input[type=radio]').each(function(inputRadio) {
            inputRadio.onClickWithContext(this, function() {
                this.__validateSubmit();
                this.__removeHighlightRow();
                inputRadio.up(1).addClassName('selectedTr');
                var formData = this.panelHTML.select('form')[0].serialize(true);
                this.saveValueChanged('radio/' + this.classPrefix + inputName, formData[inputName]);
            });
        } .bind(this));
    },
    __generateTotalPrice1Price: function(setIdentifier, dataCollection, input1) {
        var adultQuantity = jsHelper.toInt($F(input1));
        var i = 0;
        this.panelHTML.select('.ticketTable .' + setIdentifier + 'tp').each(function(eltp) {
            var item = dataCollection.values()[i];
            if (item != undefined) {
                var newTotalPrice = adultQuantity * item.price1;
                if (newTotalPrice == 0) {
                    eltp.update('-');
                }
                else {
                    eltp.update('$ ' + newTotalPrice.toFixed(2));
                }
            }
            i++;
        } .bind(this));
    },
    __generateTotalPrice2Prices: function(setIdentifier, dataCollection, input1, input2) {
        var adultQuantity = jsHelper.toInt($F(input1));
        var childQuantity = jsHelper.toInt($F(input2));
        var i = 0;
        this.panelHTML.select('.ticketTable .' + setIdentifier + 'tp').each(function(eltp) {
            var item = dataCollection.values()[i];
            if (item != undefined) {
                var newTotalPrice = adultQuantity * item.price1 + childQuantity * item.price2;
                if (newTotalPrice == 0) {
                    eltp.update('-');
                }
                else {
                    eltp.update('$ ' + newTotalPrice.toFixed(2));
                }
            }
            i++;
        } .bind(this));
    },
    __removeHighlightRow: function() {
        this.panelHTML.select('.ticketTable tbody tr').each(function(el) {
            el.removeClassName('selectedTr');
        });
    },
    __removeChecks: function() {
        this.panelHTML.select('.ticketTable tbody input[type=checkbox]').each(function(el) {
            el.checked = false;
        });

    },
    __setupStaticCalendarWithTicket: function(calendarData, radioName, ticketSelectedEl, dateSelectedEl, priceEl, totalPriceEl, q1) {
        this.calendar = new NGCalendar(this.panelHTML.select('.calendarLayer')[0], null, {
            visible: true,
            idPrefix: this.classPrefix + '-',
            daysText: 'char',
            allowWeekendSelection: true,
            onSelect: this.__onSelectedDateStatic.bind(this, dateSelectedEl, priceEl, totalPriceEl, q1)
        });

        this.panelHTML.select('input[name=' + radioName + ']').each(function(inputRadio) {
            inputRadio.onClickWithContext(this, function(event) {
                this.panelHTML.select('.calendarLayer')[0].removeClassName('disabledCalendar');

                var selected = inputRadio.readAttribute('value');
                var data = this.__getCalendarGroupByTicketValue(calendarData, selected);
                ticketSelectedEl.update(data.ticketDescription);
                var prices = [];

                data.data.each(function(item) {
                    var priceFormatted = '$' + parseFloat(item.Pri).toFixed(2);
                    if (prices.indexOf(priceFormatted) == -1) {
                        prices.push(priceFormatted);
                    }
                });

                //this._printFooter(prices);

                var currentMonth = (this.calendar.date.getMonth() + 1).toString();
                var currentYear = this.calendar.date.getFullYear().toString();
                if (currentMonth.length == 1) {
                    currentMonth = '0' + currentMonth;
                }
                var filteredData = this.__filterDataByMonthAndYear(data.data, currentMonth, currentYear);
                this.monthData = filteredData;
                this.monthData.each(function(item) {
                    var dateObject = new Date().fromString(item.De);
                    var cellId = this.classPrefix + '-date-' + (dateObject.getMonth() + 1) + '-' + dateObject.getDate() + '-' + dateObject.getFullYear();
                    var cell = $(cellId);
                    var priceFormatted = '$' + parseFloat(item.Pri).toFixed(2);
                    cell.addClassName('calendarSelected' + (prices.indexOf(priceFormatted) + 1));
                } .bind(this));

            });
        } .bind(this));
    },
    _printFooter: function(values) {
        var i = 1;
        var options = '';
        values.each(function(value) {
            options += '<div style="margin-left: 10px; display: inline;" class="calendarSelected' + i + '">&#160; &#160; &#160;</div> ' + value;
            i++;
        } .bind(this));

        var finalHtml = '<div style="text-align: center; margin-top: 6px;">' + options + '</div>';
        this.panelHTML.select('.calendarFooter')[0].update(finalHtml);
    },
    __getCalendarGroupByTicketValue: function(calendarData, value) {
        var result = null;
        calendarData.each(function(item) {
            if (item.ticketValue == value) {
                result = item;
            }
        });
        return result;
    },
    __getItemByDate: function(calendarData, date) {
        var result = null;
        calendarData.each(function(item) {
            if (item.De == date) {
                result = item;
            }
        });
        return result;
    },
    __filterDataByMonthAndYear: function(dataCollection, m, y) {
        var newData = $A();
        dataCollection.each(function(item) {
            if (item.De.startsWith(m) && item.De.endsWith(y)) {
                newData.push(item);
            }
        });
        return newData;
    },
    __setupCalendar: function(el) {
        this.calendar = new NGCalendar(this.panelHTML.select('.calendarPanel')[0], null, {
            visible: true,
            idPrefix: this.classPrefix + '-',
            daysText: 'char',
            allowWeekendSelection: true,
            onSelect: this.__onSelectedDate.bind(this, el)
        });
        this.calendar.updateHeader();
        this.calendar.populateCalendar();
        el.observe('blur', function(event) {
            this.saveValueChanged('text/' + this.classPrefix + 'dateOfArrival', $F(el));
        } .bind(this));
        jsHelper.limitSize(el, 10);

        this.panelHTML.select('[name=inputCalendar]').each(function(el) {
            el.onClickWithContext(this, function() {
                var calendarPanel = this.panelHTML.select('.calendarPanel')[0];
                var topPosition = el.positionedOffset()[1] + 'px';
                var leftPosition = el.positionedOffset()[0] + 'px';
                calendarPanel.setStyle({ 'top': topPosition, 'left': leftPosition });
                this.__closeCalendar(calendarPanel);
                calendarPanel.show();
            });
        } .bind(this));
    },
    __closeCalendar: function(_calendarPanel) {
        var inputClose = _calendarPanel.down('.btn_close_calendar');
        if (inputClose == undefined) {
            var _div = new Element('div');
            _div.setAttribute('class', 'close_calendar');
            var _inp = "<INPUT title='close calendar' alt='close calendar' type='button' class='btn_close_calendar' />";
            _div.insert(_inp);
            _calendarPanel.appendChild(_div);

            var closeCalendar = _calendarPanel.down('.btn_close_calendar');
            if (closeCalendar != null || closeCalendar != undefined) {
                Event.observe(closeCalendar, 'click', function(event) {
                    _calendarPanel.hide();
                } .bind(this));
            }
        }
    },
    __setupCalendarWithCallback: function(el, callback) {
        this.calendar = new NGCalendar(this.panelHTML.select('.calendarPanel')[0], null, {
            visible: true,
            idPrefix: this.classPrefix + '-',
            daysText: 'char',
            allowWeekendSelection: true,
            onSelect: function() {
                var dateSelected = this.calendar.options.selectedDate;
                var dateFormatted1 = jsHelper.formatDate(dateSelected, 'm/d/Y');
                el.setValue(dateFormatted1);
                var calendarPanel = this.panelHTML.select('.calendarPanel')[0];
                calendarPanel.hide();
                this.saveValueChanged('text/' + this.classPrefix + 'dateOfArrival', dateFormatted1);
                callback();
            } .bind(this, el)
        });
        this.calendar.updateHeader();
        this.calendar.populateCalendar();
        el.observe('blur', function(event) {
            this.saveValueChanged('text/' + this.classPrefix + 'dateOfArrival', $F(el));
        } .bind(this));
        jsHelper.limitSize(el, 10);

        this.panelHTML.select('[name=inputCalendar]').each(function(el) {
            el.onClickWithContext(this, function() {
                var calendarPanel = this.panelHTML.select('.calendarPanel')[0];
                var topPosition = el.positionedOffset()[1] + 'px';
                var leftPosition = el.positionedOffset()[0] + 'px';
                calendarPanel.setStyle({ 'top': topPosition, 'left': leftPosition });
                this.__closeCalendar(calendarPanel);
                calendarPanel.show();
            });
        } .bind(this));
    },
    __onSelectedDateStatic: function(dateSelectedEl, priceEl, totalPriceEl, q1) {
        var enabled = !this.panelHTML.select('.calendarLayer')[0].hasClassName('disabledCalendar');

        if (enabled) {
            var dateSelected = this.calendar.options.selectedDate;
            var dateFormatted2 = jsHelper.formatDate(dateSelected, 'm/d/Y');

            var item = this.__getItemByDate(this.monthData, dateFormatted2);
            if (item != null) {
                var dateFormatted1 = jsHelper.formatDate(dateSelected, 'F d, Y');
                dateSelectedEl.update(dateFormatted1);

                priceEl.update('$' + item.Price);
                var totalCost = parseFloat(item.Price) * parseInt($F(q1));
                totalPriceEl.update('$' + totalCost.toFixed(2));
            }
        }
    },
    __onSelectedDate: function(el) {
        var dateSelected = this.calendar.options.selectedDate;
        var dateFormatted1 = jsHelper.formatDate(dateSelected, 'm/d/Y');
        el.setValue(dateFormatted1);
        var calendarPanel = this.panelHTML.select('.calendarPanel')[0];
        calendarPanel.hide();
        this.saveValueChanged('text/' + this.classPrefix + 'dateOfArrival', dateFormatted1);
    },
    validateFields: function() {
        var formData = this.panelHTML.select('form')[0].serialize(true);
        if (this._validateInputData(formData)) {
            this.panelHTML.select('[name=inputAddToCart]').each(function(el) {
                el.removeClassName('disabledButton');
            });
        }
        else {
            this.panelHTML.select('[name=inputAddToCart]').each(function(el) {
                el.addClassName('disabledButton');
            });
        }
    },
    __filterDataGroupByProperty: function(dataCollection, property) {
        var newDataHash = $H();
        dataCollection.each(function(item) {
            if (newDataHash.get(item[property]) == undefined) {
                newDataHash.set(item[property], {
                    description: item[property],
                    productID1: '',
                    productID2: '',
                    variantID1: '',
                    variantID2: '',
                    catalog1: '',
                    catalog2: '',
                    stringPrice1: '',
                    stringPrice2: '',
                    stringTotalPrice: '-',
                    price1: '',
                    price2: '',
                    popupKey: '',
                    descriptionTicket1: '',
                    descriptionTicket2: ''
                });
            }
            var currentItem = newDataHash.get(item[property]);
            currentItem.popupKey = item[property].camelize();
            currentItem.popupKey = currentItem.popupKey.replace(' ', '');
            if (item.Age == 'Adult' || item.Age == 'All Ages') {
                currentItem.productID1 = item.ProductId;
                currentItem.variantID1 = item.ProductVariantId;
                currentItem.catalog1 = item.VirtualCatalog;
                currentItem.stringPrice1 = '$ ' + (parseFloat(item.Price)).toFixed(2);
                currentItem.price1 = parseFloat(item.Price);
                currentItem.descriptionTicket1 = item.DescriptionTicket;
            }
            else if (item.Age == 'Kid') {
                currentItem.productID2 = item.ProductId;
                currentItem.variantID2 = item.ProductVariantId;
                currentItem.catalog2 = item.VirtualCatalog;
                currentItem.stringPrice2 = '$ ' + (parseFloat(item.Price)).toFixed(2);
                currentItem.price2 = parseFloat(item.Price);
                currentItem.descriptionTicket2 = item.DescriptionTicket;
            }
        });
        return newDataHash;
    },
    __filterAnnualPassData: function(dataCollection) {
        var passes = $H();
        dataCollection.each(function(item) {
            var index = item.PassType.replace(' ', '').camelize();
            if (passes.get(index) == undefined) {
                passes.set(index, {
                    description: '',
                    productID1: '',
                    productID2: '',
                    variantID1: '',
                    variantID2: '',
                    catalog1: '',
                    catalog2: '',
                    stringPrice1: '',
                    stringPrice2: '',
                    stringTotalPrice: '-',
                    price1: '',
                    price2: '',
                    subProductID1: '',
                    subProductID2: '',
                    subVariantID1: '',
                    subVariantID2: '',
                    subCatalog1: '',
                    subCatalog2: '',
                    popupKey: '',
                    descriptionTicket1: '',
                    descriptionTicket2: '',
                    isCo: 'False',
                    comTicket: '',
                    CoPid: '',
                    CoPvid: ''
                });
            }
            var currentItem = passes.get(index);
            currentItem.description = item.PassType;
            currentItem.popupKey = index;

            if (item.Age == 'Adult') {
                if (item.IsFlexPay == "False") {
                    currentItem.productID1 = item.ProductID;
                    currentItem.variantID1 = item.ProductVariantID;
                    currentItem.catalog1 = item.CatalogName;
                    currentItem.price1 = parseFloat(item.Price);
                    currentItem.stringPrice1 = '$ ' + parseFloat(item.Price).toFixed(2);
                    currentItem.descriptionTicket1 = item.DescriptionTicket;
                }
                else {
                    currentItem.subProductID1 = item.ProductID;
                    currentItem.subVariantID1 = item.ProductVariantID;
                    currentItem.subCatalog1 = item.CatalogName;
                    currentItem.subDescription = item.FlexPayDescription;
                }
            }
            if (item.Age == 'Kid') {
                if (item.IsFlexPay == "False") {
                    currentItem.productID2 = item.ProductID;
                    currentItem.variantID2 = item.ProductVariantID;
                    currentItem.catalog2 = item.CatalogName;
                    currentItem.price2 = parseFloat(item.Price);
                    currentItem.stringPrice2 = '$ ' + parseFloat(item.Price).toFixed(2);
                    currentItem.descriptionTicket2 = item.DescriptionTicket;
                }
                else {
                    currentItem.subProductID2 = item.ProductID;
                    currentItem.subVariantID2 = item.ProductVariantID;
                    currentItem.subCatalog2 = item.CatalogName;
                    currentItem.subDescription = item.FlexPayDescription;
                }
            }
            if (item.IsCo == 'True' && currentItem.isCo == 'False') {
                currentItem.isCo = 'True';
                currentItem.CoPid = item.CoPid;
                currentItem.CoPvid = item.CoPvid;
                currentItem.comTicket = '<img src="/images/commemorativetix_gfx.png" alt="" title="" />';
            }
        });
        return passes;
    },
    __filterDayTicketByParkAndBlockout: function(dataCollection, parkNumber, blockout) {
        var newData = $A();
        dataCollection.each(function(item) {
            if (item.Pn == parkNumber && item.Bd == blockout) {
                newData.push(item);
            }
        });
        var newDataHash = $H();
        newData.each(function(item) {
            if (newDataHash.get(item.Dn) == undefined) {
                newDataHash.set(item.Dn, {
                    description: item.Des,
                    productID1: '',
                    productID2: '',
                    variantID1: '',
                    variantID2: '',
                    catalog1: '',
                    catalog2: '',
                    stringPrice1: '',
                    stringPrice2: '',
                    stringTotalPrice: '-',
                    price1: '',
                    price2: '',
                    descriptionTicket1: '',
                    descriptionTicket2: '',
                    popupKey: '',
                    isCo: 'False',
                    comTicket: '',
                    CoPid: '',
                    CoPvid: ''
                });
            }
            var currentItem = newDataHash.get(item.Dn);

            currentItem.popupKey = parkNumber + '_' + item.Dn;

            if (item.Age == "Adult") {
                currentItem.productID1 = item.Pid;
                currentItem.variantID1 = item.Pvid;
                currentItem.catalog1 = item.Vcn;
                currentItem.stringPrice1 = '$ ' + (parseFloat(item.Pri)).toFixed(2);
                currentItem.price1 = parseFloat(item.Pri);
                currentItem.descriptionTicket1 = item.Det;
            }
            else {
                currentItem.productID2 = item.Pid;
                currentItem.variantID2 = item.Pvid;
                currentItem.catalog2 = item.Vcn;
                currentItem.stringPrice2 = '$ ' + (parseFloat(item.Pri)).toFixed(2);
                currentItem.price2 = parseFloat(item.Pri);
                currentItem.descriptionTicket2 = item.Det;
            }
            if (item.IsCo == 'True' && currentItem.isCo == 'False') {
                currentItem.isCo = 'True';
                currentItem.CoPid = item.CoPid;
                currentItem.CoPvid = item.CoPvid;
                currentItem.comTicket = '<img src="/images/commemorativetix_gfx.png" alt="" title="" />';
            }

        });
        return newDataHash;
    },
    __getFilteredItemByParkAndDay: function(dataCollection, parkNumber, day) {
        var result = null;
        dataCollection.each(function(item) {
            if (item.value.popupKey == parkNumber + '_' + day) {
                result = item;
            }
        });
        return result.value;
    },
    __getFilteredItemByKey: function(dataCollection, key) {
        var result = null;
        dataCollection.each(function(item) {
            if (item.value.popupKey == key) {
                result = item;
            }
        });
        return result.value;
    },
    __filterDayTicketByPark: function(dataCollection, parkNumber) {
        var newData = $A();
        dataCollection.each(function(item) {
            if (item.Pn == parkNumber) {
                newData.push(item);
            }
        });
        var newDataHash = $H();
        newData.each(function(item) {
            if (newDataHash.get(item.Dn) == undefined) {
                newDataHash.set(item.Dn, {
                    description: item.Des,
                    productID1: '',
                    productID2: '',
                    variantID1: '',
                    variantID2: '',
                    catalog1: '',
                    catalog2: '',
                    stringPrice1: '',
                    stringPrice2: '',
                    stringTotalPrice: '-',
                    price1: '',
                    price2: '',
                    descriptionTicket1: '',
                    descriptionTicket2: '',
                    popupKey: '',
                    isCo: 'False',
                    comTicket: '',
                    CoPid: '',
                    CoPvid: ''
                });
            }
            var currentItem = newDataHash.get(item.Dn);
            currentItem.popupKey = parkNumber + '_' + item.Dn;
            if (item.Age == "Adult") {
                currentItem.productID1 = item.Pid;
                currentItem.variantID1 = item.Pvid;
                currentItem.catalog1 = item.Vcn;
                currentItem.stringPrice1 = '$ ' + (parseFloat(item.Pri)).toFixed(2);
                currentItem.price1 = parseFloat(item.Pri);
                currentItem.descriptionTicket1 = item.Det;
            }
            else {
                currentItem.productID2 = item.Pid;
                currentItem.variantID2 = item.Pvid;
                currentItem.catalog2 = item.Vcn;
                currentItem.stringPrice2 = '$ ' + (parseFloat(item.Pri)).toFixed(2);
                currentItem.price2 = parseFloat(item.Pri);
                currentItem.descriptionTicket2 = item.Det;
            }
            if (item.IsCo == 'True' && currentItem.isCo == 'False') {
                currentItem.isCo = 'True';
                currentItem.CoPid = item.CoPid;
                currentItem.CoPvid = item.CoPvid;
                currentItem.comTicket = '<img src="/images/commemorativetix_gfx.png" alt="" title="" />';
            }
        });
        return newDataHash;
    },
    __loadValues: function(variables) {
        var newvals = [];
        variables.each(function(item) {
            var splitted = item.split('/');
            newvals.push(splitted[0] + '/' + this.classPrefix + splitted[1]);
        } .bind(this));
        newvals = newvals.join('|');
        new Ajax.Request('/home.aspx/GetValuesInSession', {
            contentType: 'application/json',
            postBody: Object.toJSON({
                strValue: newvals
            }),
            onSuccess: function(response) {
                if (response.responseText.evalJSON().d != "") {
                    this.previousValues = response.responseText.evalJSON().d.evalJSON();
                }
                this.__setPreviousValues();
                this.__validateSubmit();
                this._calculateTotalPrices();
            } .bind(this)
        });
    },
    __setPreviousValues: function() {
        for (var valueIndex in this.previousValues) {
            var splitted = valueIndex.split('/');
            var valueType = splitted[0];
            var valueName = splitted[1].substring(this.classPrefix.length);
            switch (valueType) {
                case 'text':
                    this.panelHTML.select('[name=' + valueName + ']')[0].writeAttribute({ value: this.previousValues[valueIndex] });
                    break;
                case 'radio':
                    this.panelHTML.select('[name=' + valueName + ']').each(function(el) {
                        if (el.readAttribute('value') == this.previousValues[valueIndex]) {
                            el.writeAttribute({ 'checked': 'checked' });
                            this.__removeHighlightRow();
                            el.up(1).addClassName('selectedTr');
                            var nextRow = el.up(1).next(0);
                            if (nextRow != undefined && nextRow.readAttribute('class') == 'subProduct') {
                                nextRow.addClassName('selectedTr');
                            }
                        }
                    } .bind(this));
                    break;
                case 'radioWithCalendar':
                    this.panelHTML.select('[name=' + valueName + ']').each(function(el) {
                        if (el.readAttribute('value') == this.previousValues[valueIndex]) {
                            el.writeAttribute({ 'checked': 'checked' });
                            el["click"]();
                        }
                    } .bind(this));
                    break;
                case 'checkbox':
                    this.panelHTML.select('[name=' + valueName + ']').each(function(el) {
                        if (el.readAttribute('value') == this.previousValues[valueIndex]) {
                            el.checked = true;
                            this.__removeHighlightRow();
                            el.up(1).addClassName('selectedTr');
                            var nextRow = el.up(1).previous(0);
                            if (nextRow != undefined) {
                                nextRow.addClassName('selectedTr');
                            }
                            //show flexpay message
                            var FlexPayMessage = this.panelHTML.select('[id=FlexPayMessage]')[0];
                            if (FlexPayMessage != null) {
                                FlexPayMessage.show();
                            }
                        }
                    } .bind(this));
                    break;
                case 'calendar':
                    var dateObject = new Date().fromString(this.previousValues[valueIndex]);

                    this.calendar.options.selectedDate = dateObject;
                    this.calendar.date = dateObject;
                    this.calendar.updateHeader();
                    this.calendar.populateCalendar();

                    var cellId = this.classPrefix + '-date-' + (dateObject.getMonth() + 1) + '-' + dateObject.getDate() + '-' + dateObject.getFullYear();
                    var cell = this.panelHTML.select('[id=' + cellId + ']')[0];
                    if (cell != undefined) {


                        cell.addClassName('ng-selected-day');
                        this.calendar.options.onSelect();
                        //actualizar details
                    }
                    break;
            }
        }
    },
    loadValues: function(variables) {
        variables = variables.join('|');
        new Ajax.Request('/home.aspx/GetValuesInSession', {
            contentType: 'application/json',
            postBody: Object.toJSON({
                strValue: variables
            }),
            onSuccess: function(response) {
                if (response.responseText.evalJSON().d != "") {
                    this.previousValues = response.responseText.evalJSON().d.evalJSON();
                }
                this.setPreviousValues();
            } .bind(this)
        });
    },
    saveValueChanged: function(variable, value) {
        value = value.trim();

        if (variable.endsWith('dateOfArrival')) {
            this.SetDateArrival(value);
        }

        //if (value != "") {
        new Ajax.Request('/home.aspx/SetValuesInSession', {
            contentType: 'application/json',
            postBody: Object.toJSON({
                strValue: variable + '=' + value
            }),
            onSuccess: function(response) {
            } .bind(this)
        });
        //}
    },
    SetDateArrival: function(value) {
        value = value.trim();
        new Ajax.Request('/home.aspx/SetDateArrival', {
            contentType: 'application/json',
            postBody: Object.toJSON({
                strDate: value
            }),
            onSuccess: function(response) {
            } .bind(this)
        });
    }
});
