/* Minification failed. Returning unminified contents.
(5244,5,5248,6): run-time error JS1314: Implicit property name must be identifier: mounted() {
        document.getElementById("forgotPasswordForm").addEventListener("submit", function (event) {
            event.preventDefault()
        });
    }
(13893,9,13895,10): run-time error JS1314: Implicit property name must be identifier: dateFilterApplied() {
            return this.DateFilterApplied();
        }
(17740,9,17752,10): run-time error JS1314: Implicit property name must be identifier: cartHasMembership() {
            const { cartItems } = window.CartStore.state;

            if (cartItems && cartItems.length > 0) {
                for (let i = 0; i < cartItems.length; i += 1) {
                    if (cartItems[i].CartItemTypeID === window.CartItemType.MEMBERSHIP) {
                        return true;
                    }
                }
            }

            return false;
        }
(17753,9,17762,10): run-time error JS1314: Implicit property name must be identifier: priceDisplayed() {
            if (this.store.state.startDate != null && this.store.state.endDate != null
                && !this.store.state.priceLoading && !this.store.state.priceLoadError
                && !this.store.state.noTariffsAvailable && !this.selectedAllotment.UnavailableMessage
                && !this.store.state.isOnDealPage && !this.cartHasMembership) {
                return true;
            }

            return false;
        }
(17795,5,17799,6): run-time error JS1314: Implicit property name must be identifier: mounted() {
        if (this.props.searchMode) {
            this.toggleResponsiveBookingWidget();
        }
    }
 */
Vue.component('accommodation-card-panel', {
    props: ['ParkId', 'AccommodationDetails', 'Props'],
    data: function () {
        return {
            state: window.AccommodationStore.state,
            store: window.AccommodationStore
        };
    },
    computed: {
        sites: function () {
            return _.filter(this.state.accommodations, function (accom) { return accom.AccommodationType === "SITES"; });
        },
        cabins: function () {
            return _.filter(this.state.accommodations, function (accom) { return accom.AccommodationType === "CABINS"; });
        }
    },
    created: function () {
        if (this.ParkId != "")
        {
            this.state.ParkId = this.ParkId;
        }

        if (this.AccommodationDetails != undefined)
        {
            this.state.accommodations = this.AccommodationDetails;
        }
        this.store.GetDailyFromPrices();
    }
});

;
window.AccommodationEventBus = new Vue();

;

Vue.component('accommodation-handler', {

    template: "<div style='display:none'></div>",
    props:
    {

    },
    data: function () {
        return {
            subscribers: [],
            websiteHub: null,
            store: window.AccommodationStore
        }
    },
    methods: {
        bindFilterEvents: function () {
            var self = this;

            window.AccommodationEventBus.$on('date-filter-update', function (data) {

                if (window.DateFilterStore.state.rangeSelected) {
                    self.store.state.accommodationLoading = true;

                    self.store.state.StartDate = data.start;
                    self.store.state.EndDate = data.end;

                    self.store.CallPms();
                }
            });

            window.AccommodationEventBus.$on('quick-booking-date-changed', function (data) {

                self.store.state.StartDate = data.start;
                self.store.state.EndDate = data.end;

                self.store.CallPms();
            });

            window.AccommodationEventBus.$on('guest-filter-update', function (data) {
                //self.store.state.accommodationLoading = true;
                self.store.state.NumAdults = data.adults;
                self.store.state.NumChildren = data.children;
                self.store.state.NumInfants = data.infants;
                /*Call pms to update for new filter*/
                self.store.CallPms();

                if (window.BookingStore != undefined) {
                    if (!window.BookingStore.state.quickBooking.isPark) {
                        self.updateFilterPersonaScore()
                    }
                }
                else
                {
                    self.updateFilterPersonaScore()
                }
            });

            window.AccommodationEventBus.$on('pets-filter-update', function (data) {
                self.store.state.PetFriendly = data.isOn;
            });

            window.AccommodationEventBus.$on('type-filter-update', function (accommodationTypes) {
                self.store.state.Type = accommodationTypes;

                window.AccommodationStore.FilteredByAccommodationType();
            });

            window.AccommodationEventBus.$on('price-filter-update', function (data) {
                self.store.state.MinPriceRange = data.startPoint;
                self.store.state.MaxPriceRange = data.endPoint;
            });
        },
        updateFilterPersonaScore: function ()
        {
            var self = this;
            var url = "";

            /*Post activity for personalisation*/
            if (self.store.state.NumAdults > 2) {
                url += "/api/Personalization/FilteredByGroup";
            }
            else if (self.store.state.NumChildren >= 1 || self.store.state.NumInfants) {
                url += "/api/Personalization/FilteredByFamily";
            }
            else if (self.store.state.NumAdults == 2 && self.store.state.NumChildren == 0 && self.store.state.NumInfants == 0) {
                url += "/api/Personalization/FilteredByNomad";
            }

            if (url != "") {
                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    success: function () {
                    },
                    error: function (xhr, ajaxOptions, thrownError) {

                    }

                });
            }
        },
    },
    computed: {
        parks: function () {
            return this.store.state.ParkFilter.Results;
        }
    },
    mounted: function () {
        this.bindFilterEvents();
    }
});
;
window.AccommodationStore = {
    state: {
        accommodations: [],
        accommodationLoading: true,
        callingPms: false,

        ParkId: 0,
        //Filters
        StartDate: moment().startOf('day'),
        EndDate: moment().startOf('day').add(1, 'day'),
        PetFriendly: false,
        Type: [],
        showCabinList: true,
        showSiteList: true,
        canApplyDates: false,
        checkAccomParam: true,
        NumAdults: 1,
        NumChildren: 0,
        NumInfants: 0,
        MinPriceRange: 0,
        MaxPriceRange: 999,
        DEFAULT_ADULTS: 1,
        DEFAULT_CHILDREN: 0,
        DEFAULT_INFANTS: 0,
        DEFAULT_START_DATE: moment().startOf('day'),
        DEFAULT_END_DATE: moment().startOf('day').add(1, 'day'),
        numberOfNights: 1,
    },
    SwapToCabins: function () {
        //store the default values in cookie
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }
            cookie["Accommodation"] = ["Cabins"];
            CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
        }
        catch (e) {
        }
        document.getElementById("accommodationFlexCabins").style.order = "1";
        document.getElementById("accommodationFlexSites").style.order = "2";
        document.getElementById("mapButtonCabins").style.display = "inline-block";
        document.getElementById("mapButtonSites").style.display = "none";
        window.AccommodationFilterStore.state[0].data = ["Cabins"];
    },
    SwapToSites: function () {
        //store the default values in cookie
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }
            cookie["Accommodation"] = ["Sites"];
            CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
        }
        catch (e) {
        }
        document.getElementById("accommodationFlexCabins").style.order = "2";
        document.getElementById("accommodationFlexSites").style.order = "1";
        document.getElementById("mapButtonCabins").style.display = "none";
        document.getElementById("mapButtonSites").style.display = "inline-block";
        window.AccommodationFilterStore.state[0].data = ["Sites"];
    },
    IsPriceFilterApplied: function () {
        return !(this.state.MinPriceRange === window.TwoSliderFilterStore.default.startPoint && this.state.MaxPriceRange === window.TwoSliderFilterStore.default.endPoint)
    },
    ProcessAvailCacheData: function (availCacheData) {

        var tempList = [];
        for (var i = 0; i < this.state.accommodations.length; i++) {
            var accommodation = _.clone(this.state.accommodations[i]);

            var availData = _.find(availCacheData, { AccommodationID: accommodation.AccommodationID });

            if (availData !== null && typeof availData !== 'undefined') {
                accommodation.AvailabilityCacheData = availData;
            }
            else {
                console.log('Data not returned from availability cache.');
            }
            tempList.push(accommodation);
        }

        this.state.accommodations = tempList;


    },
    GetDailyFromPrices: function () {
        var self = this;
        this.state.accommodationLoading = true;

        var startDate = moment(new Date(), "DD/MM/YYYY").format();
        request = {
            ParkID: this.state.ParkId,
            Date: startDate
        };

        $.ajax({
            type: 'GET',
            url: '/api/Deals/GetDailyAvailability',
            contentType: 'application/json; charset=utf-8',
            data: request,
            success: function (data) {
                var response = JSON.parse(data);
    
                self.ProcessAvailCacheData(response.Accommodations);
                self.state.accommodationLoading = false;

            },
            error: function (xhr, ajaxOptions, thrownError) {

            }

        });
    },
    FilteredByAccommodationType: function () {

        var self = this;

        //if we only get a single item in the array, lets make sure that item is on top
        if (self.state.Type.length === 1 && !this.state.checkAccomParam) {
            if (self.state.Type[0].toUpperCase() === "CABINS") {

                this.state.showCabinList = true;
                this.state.showSiteList = false;
                self.SwapToCabins();
            }
            else if (self.state.Type[0].toUpperCase() === "SITES") {

                this.state.showCabinList = false;
                this.state.showSiteList = true;
                self.SwapToSites();
            }
        }
        else {
            this.state.showCabinList = true;
            this.state.showSiteList = true;

            //if we are clearing the selection, we want to change back to the default order.
            if (self.state.Type.length === 0 || this.state.checkAccomParam) {

                var urlParam = Common.GetUrlParameter("accommodationType");
                this.state.checkAccomParam = false;

                if (urlParam == "") {
                    if (self.state.Type.length === 1) {
                        if (self.state.Type[0].toUpperCase() === "CABINS") {

                            this.state.showCabinList = true;
                            this.state.showSiteList = false;
                            self.SwapToCabins();
                        }
                        else if (self.state.Type[0].toUpperCase() === "SITES") {

                            this.state.showCabinList = false;
                            this.state.showSiteList = true;
                            self.SwapToSites();
                        }
                    }
                }
                else
                {
                    if (urlParam.toUpperCase() === "CABINS") {
                        self.SwapToCabins();
                    }
                    else if (urlParam.toUpperCase() === "SITES") {
                        self.SwapToSites();
                    }
                }
            }
        }


    },
    prefillSelections: function () {
        var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
        if (cookie != "") {
            cookie = JSON.parse(cookie);

            if (!!cookie.Dates) {
                this.state.startDate = moment(cookie.Dates.start);
                this.state.endDate = moment(cookie.Dates.end);

                this.state.dataPrefilled = true;
            }

            if (!!cookie.Guests) {
                this.state.adults = cookie.Guests.adults;
                this.state.children = cookie.Guests.children;
                this.state.infants = cookie.Guests.infants;

                //For quick booking, make sure we update the accommodation store values
                if (window.AccommodationStore != undefined) {
                    window.AccommodationStore.state.NumAdults = cookie.Guests.adults;
                    window.AccommodationStore.state.NumChildren = cookie.Guests.children;
                    window.AccommodationStore.state.NumInfants = cookie.Guests.infants;
                }

                this.state.dataPrefilled = true;
            }
        }
    },
    CallPms: function () {
        var self = this;
        if (self.state.StartDate != undefined) {
            var newStartDate = moment(self.state.StartDate).format('YYYY MM DD');
            var newEndDate = moment(self.state.EndDate).format('YYYY MM DD');
        }

        self.state.accommodationLoading = true;
        self.state.callingPms = true;

        // Ensure cookie values are aquired;
        self.prefillSelections();

        var parkAvailabilityRequest =
        {
            "ArrivalDate": newStartDate,
            "DepartingDate": newEndDate,
            "NumAdults": self.state.NumAdults,
            "NumKids": self.state.NumChildren,
            "NumInfants": self.state.NumInfants,
            "ParkIDs": [self.state.ParkId],
            "UseCache": true,
        };

        $.ajax({
            type: 'GET',
            url: '/api/Booking/GetAllParkAvailability',
            contentType: 'application/json; charset=utf-8',
            data: parkAvailabilityRequest,
            success: function (data) {
                if (data.ResponseStatus == eHttpResponseStatus.Ok) {
                   
                    window["AccommodationEventBus"].$emit('all-park-pms-availability-update', data);
                    self.state.callingPms = false;

                    for (let i = 0; i < self.state.accommodations.length; i++) {                       
                            const item = data.AllAccommodations.find(x => x.AccommodationID == self.state.accommodations[i].AccommodationID);

                        self.state.accommodations[i].Price = item.Allotment[0].Total
                        self.state.accommodations[i].Discount = item.Allotment[0].Discount
                        }            
                }
                else {
                    Common.ShowErrorStatusMessages(data.StatusMessages);
                    self.state.accommodationLoading = false;
                    self.state.callingPms = false;
                }
            },
            error: function (xhr, ajaxOptions, thrownError) {
                self.state.accommodationLoading = false;
                self.state.callingPms = false;
            }
        });
    },
};
//Changes the order of cabins/sites based off of url used to open page
if (typeof ACCOMMODATION_TYPE !== "undefined" && ACCOMMODATION_TYPE && ACCOMMODATION_TYPE != "")
{
    if (ACCOMMODATION_TYPE.toLowerCase() == "sites") {
        document.getElementById("accommodationFlexCabins").style.order = "2";
        document.getElementById("mapButtonCabins").style.display = "none";
        document.getElementById("mapButtonSites").style.display = "inline-block";
    } else
    {
        document.getElementById("mapButtonSites").style.display = "none";
    }
};
Vue.component('view-image-button', {

    props: ['images'],
    template: '#AccommodationViewImages',

    data: function () {
        return {
        }
    },
    methods: {
        openGallery: function () {
            var pswpElement = document.querySelectorAll('.pswp')[0];

            // build items array
            var items = [];

            for (var i = 0; i < this.images.length; i++) {
                items.push({
                    src: this.images[i].ImageURL,
                    w: 1200,
                    h: 800,
                    title: this.images[i].Description
                });
                
            }

            // define options (if needed)
            var options = {
                // optionName: 'option value'
                // for example:
                index: 0 // start at first slide
            };

            // Initializes and opens PhotoSwipe
            window.gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
            window.gallery.init();
        }
    },
    created: function () {


    }

});;
Vue.component('feature-list-data-wrapper', {
    props: ['ParkId','FeatureList'],
    data: function () {
        return {
            featureItemList: [],
            featureMoreItemList: [],
            morePage: false,
            count:0
        }
    },
    methods: {
    },
    mounted: function () {

        var list = this.FeatureList;

        if (list.length <= 6)
        {
            this.featureItemList = this.FeatureList;
            this.morePage = false;
        }
        else {
            this.featureItemList = this.FeatureList.slice(0, 6);
            this.featureMoreItemList = this.FeatureList.slice(6);
            this.morePage = true;
            this.count = this.FeatureList.length;
        }

    }

})

;
Vue.component('more-feature-data-wrapper', {
    props: ['FeatureCount', 'MoreFeatureList'],
    data: function () {
        return {
            active: false,
            moreFeatureList:[],
            count:0
        }
    },
    methods: {
        toggle: function () {
            if (this.active) {
                this.active = false;
            } else {
                this.active = true;
            }
        },
    },
    mounted: function () {
        this.count = this.FeatureCount;
        this.moreFeatureList = this.MoreFeatureList;
    }

})

;
Vue.component('action-confirmation', {
    props: ['index'],
    template: "#CART_ITEM_ACTION_CONFIRMATION_TEMPLATE",

    methods: {
        removeItemFromCart:function(index) {
            window.CartStore.removeItemFromCart(index);
        },
        cancelRemoveItemFromCart:function(index) {
            window.CartStore.toggleMarkItemForRemoval(index);
        }

    },
});
;
Vue.component('cart', {
    template: "#CART_TEMPLATE",
    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {
            state: window.CartStore.state
        }
    },
    computed: {

        hasItems: function () {
            return _.some(this.state.cartItems, function (item) {

                if (item.CartItemTypeID == window.CartItemType.ACCOMMODATION) {
                    return true;
                }
                if (item.CartItemTypeID == window.CartItemType.GIFTCARD) {
                    return true;
                }
                if (item.CartItemTypeID == window.CartItemType.MEMBERSHIP) {
                    return true;
                }
                if (item.CartItemTypeID == window.CartItemType.PRODUCT) {
                    return true;
                }

                return false;

            });
        }

    },
    methods: {
        show: function () {
            this.$refs.modalWrapper.openModal();
        }
    },

});
;
//this creates an event bus where we can listen for items
//and events relating to the cart functionality
window.CartEventBus = new Vue();


window.CartEvents = {

    SET_CART_STATE: "set-cart-state",
    REMOVE_ITEM_FROM_CART: "remove-item-from-cart",
    LOADED: 'loaded',
    STOP_PROCESSING: 'stop-processing',
    SET_CART_ERROR: 'set-cart-error',

    ADD_BOOKING: "add-booking",

    ADD_PRODUCTS: "add-products",
    UPDATE_PRODUCT: "update-product",

    ADD_MEMBERSHIP: "add-membership",
    REMOVE_MEMBERSHIP: 'remove-membership',

    ADD_GIFTCARDS: "add-giftcards",
    ADD_GIFTCARD_REDEMPTION: "add-giftcard-redemption",
    ADD_GIFTCARD_POSTAGE: "add-giftcard-postage",
    REMOVE_GIFTCARD_POSTAGE: "remove-girftcard-postage",
    ADD_GIFTCARD_PROMOCODE_TO_CART: "add-giftcard-promocode-to-cart",
    CLOSE_CART_MODAL: "close-cart-modal",


    POPULATE_CART:"populate-cart",
    
};

window.CartItemType = {
    ACCOMMODATION: 1,
    GIFTCARD: 2,
    MEMBERSHIP: 3,
    PRODUCT: 4,
    GIFTCARD_REDEMPTION: 5,
    GIFTCARD_POSTAGE_FEE: 6,
    PROMOTION: 7
};

window.CartState = {
    NEW: 1,
    EDIT: 2,
    SIGN_IN: 3,
    CHECKOUT_EXTRAS: 4,
    CHECKOUT_DETAILS: 5,
    CHECKOUT_PAYMENT: 6,
    PAID: 7,
    ERROR: 8,
    LOADING: 9,
};

;

Vue.component('cart-footer', {

    template: "#CART_FOOTER_TEMPLATE",
    mixins: [MIXIN_CHECK_OVERLAPPING_BOOKINGS, MIXIN_CHECKOUT_DEALS,MIXIN_MEMBERSHIP,MIXIN_CART],
    props:['responsive-footer', 'continue-button'],
    data: function () {
        return {
            state: window.CartStore.state,
            checkoutState: {},
            continueButtonBool: this.continueButton,
            displayPaymentRequestOnDOM: false,
        }
    },

    computed: {
        CartStates: function () {
            return window.CartState;
        },
        
        showContinueButton: function ()
        {
            //For mobile/tablet the 'continue button' in the cart will only close the modal. Not progress checkout.
            return (this.$data.continueButtonBool || (this.$mq != 'sm' && this.$mq != 'md' && this.$mq != 'lg')) && window.CheckoutStore != null;
        },

        hasUnavailableItems: function () {
            return (_.some(this.state.cartItems, { IsUnavailable: true }) || this.showAddMembership);
        },

        cartProcessing: function () {
            return this.state.cartProcessing;
        },
        cartError: function () {
            return this.state.cartError;
        },
        cartPaymentState: function () {
            return this.state.cartState == this.CartStates.CHECKOUT_PAYMENT;
        },
        memberLoggedIn: function () {
            return !!window.LoginStore.state.membership;
        },
        showZipPayButton: function () {
            return this.checkoutState.paymentType == "zipPay" && this.cartPaymentState;
        },
        showPaymentRequestButton: function () {
            return this.checkoutState.paymentType == "googleapple" && this.cartPaymentState;
        },
        showAddMembership: function () {

            if (window.CartStore.state.cartState == window.CartState.CHECKOUT_EXTRAS || window.CartStore.state.cartState == window.CartState.CHECKOUT_DETAILS || window.CartStore.state.cartState == window.CartState.CHECKOUT_PAYMENT) {
                if (this.hasMemberOnlyDeal) {
                    if (this.cartHasMembership) {
                        return false;
                    }

                    if (!this.isLoggedIn || this.isHolidayPerksMember) {
                        return true;
                    }
                }
            }

            return false;
        },
        showPaymentRequestButtonDOM: function () {
            return this.displayPaymentRequestOnDOM
        },
        disablePayButton: function () {
            return this.checkoutState.paymentType == "" && this.cartPaymentState && !this.cartHasGiftcardRedemption && !this.cartHasPromocode;
        },
    },

    methods: {
        closeCheckoutModal: function ()
        {
            window.CartEventBus.$emit(window.CartEvents.CLOSE_CART_MODAL);
        },
        progressCheckout: function () {
            if (this.state.cartState == window.CartState.EDIT) {
                window.location.href = "/checkout";
            }
            else {
                window.CheckoutEventBus.$emit(window.CheckoutEvents.ATTEMPT_PROGRESS_CHECKOUT);
            }
        },
        addMembership: function () {
            window.CartEventBus.$emit(window.CartEvents.ADD_MEMBERSHIP, function () {
            }, function (err) {
                Common.ShowError("Unable to add membership to cart.")
            });
        },
        reportFacebookAnalytics: function ()
        {
            if (this.state.cartState == CartState.PAID)
            {
                var value = this.DisplayPriceWithDecimals(this.paymentRequired);

                fbq('track', 'Purchase', {
                    value: { value: value },
                    currency: 'AUD',
                });
            }
        },
        checkPaymentRequestDisplay: function () {
            console.log('CHECKING RESPONSIVENESS');
            if (this.responsiveFooter == "true") {
                this.displayPaymentRequestOnDOM = $(window).width() <= 1366;
            } else {
                this.displayPaymentRequestOnDOM = $(window).width() > 1366;
            }
        }
    },
    mounted: function () {
        var self = this;

        if (window.CheckoutEventBus) {
            this.checkoutState = window.CheckoutStore.state;
        }

        window.addEventListener('resize', self.checkPaymentRequestDisplay);

        self.checkPaymentRequestDisplay();
    }


});
;

Vue.component('cart-handler', {

    template: "<div style='display:none'></div>",

    mounted: function () {

        //window.CartEventBus.$on(window.CartEvents.ADD_SINGLE_ITEM_TO_CART, function (payload) {
        //    window.CartStore.addItemToCart(payload);

        //    //open the cart
        //    $('#cartModal > span').first().click()
        //});

        window.CartEventBus.$on(window.CartEvents.CLOSE_CART_MODAL, function () {
            window.CartStore.closeCart();
        });

        window.CartEventBus.$on(window.CartEvents.ADD_BOOKING, function (booking,success,error) {
            window.CartStore.addBooking(booking,success,error);
        });

        window.CartEventBus.$on(window.CartEvents.ADD_PRODUCTS, function (payload,success,error) {
            window.CartStore.addProducts(payload,success,error);
        });

        window.CartEventBus.$on(window.CartEvents.ADD_GIFTCARDS, function (payload, success, error) {
            window.CartStore.addGiftcards(payload, success, error);
        });

        window.CartEventBus.$on(window.CartEvents.ADD_MEMBERSHIP, function (success, error) {
            window.CartStore.addMembership(success, error);
        });

        window.CartEventBus.$on(window.CartEvents.REMOVE_MEMBERSHIP, function (success, error) {
            window.CartStore.removeMembership(success, error);
        });

        window.CartEventBus.$on(window.CartEvents.UPDATE_PRODUCT, function (payload, success, error) {
            window.CartStore.updateProduct(payload, success, error);
        });

        window.CartEventBus.$on(window.CartEvents.POPULATE_CART, function (payload) {
            window.CartStore.repopulateCart(payload);
        });

        window.CartEventBus.$on(window.CartEvents.ADD_GIFTCARD_PROMOCODE_TO_CART, function (payload, success, error) {
            window.CartStore.addGiftcardPromocodeToCart(payload, success, error);
        });
      

        window.CartEventBus.$on(window.CartEvents.REMOVE_ITEM_FROM_CART, function (payload,success,error) {
            window.CartStore.removeItemFromCart(payload,success,error);
        });

        window.CartEventBus.$on(window.CartEvents.SET_CART_STATE, function (payload) {
            window.CartStore.setCartState(payload);
        });

        window.CartEventBus.$on(window.CartEvents.STOP_PROCESSING, function () {
            window.CartStore.stopProcessing();
        });

        window.CartEventBus.$on(window.CartEvents.SET_CART_ERROR, function (payload) {
            window.CartStore.setCartError(payload);
        });

        window.CartEventBus.$on(window.CartEvents.ADD_GIFTCARD_POSTAGE, function (payload, success, error) {
            window.CartStore.addGiftcardPostage(payload, success, error);
        });
        window.CartEventBus.$on(window.CartEvents.REMOVE_GIFTCARD_POSTAGE, function (payload, success, error) {
            window.CartStore.removeGiftcardPostage(payload, success, error);
        });


        //we want to bind to the checkout events if we are on the checkout page
        if (window.CheckoutEventBus != null) {
            window.CheckoutEventBus.$on(window.CheckoutEvents.PROGRESS_CHECKOUT, function () {
                window.CartStore.progressCheckout();
            });
            window.CheckoutEventBus.$on(window.CheckoutEvents.PROCESS_PAYMENT, function (payload) {
                window.CartStore.setCartProcessing();
            });
        }

        //we want to capture the login event so that we can go fetch the cart
        window.LoginEventBus.$on(window.LoginEvents.AUTHENTICATED, function () {
            window.CartStore.retrieveCart();
        });


        if(typeof(CART) != 'undefined'){
            window.CartStore.setCartState(window.CartState.PAID);
            window.CartStore.repopulateCart(CART);

            window.CartEventBus.$emit(window.CartEvents.LOADED);
            if (!window.featureFlags.BAPI_3113_google_analytics_data_layer_update) {
                window.GoogleAnalyticsEcommerceEventBus.$emit('PURCHASE');
            }
        }
        else{
            window.CartStore.retrieveCart();
        }

    },
    methods: {
    }
});
;
Vue.component('cart-sign-in', {
    template: "#CART_SIGN_IN_TEMPLATE",
    data: function () {
        return {
            
        }
    },
    methods: {

    },
    mounted: function () {
        var self = this;

        window.LoginEventBus.$on(window.LoginEvents.HIDE_LOGIN_MODAL, function (callback) {

            //self.$refs.modalWrapper.showModal = false;
            //$('body').removeClass('no-scroll');

            //self.showCheckout();

            //we need to do this to give the modal tranisition time to slide out
            //before we update
            setTimeout(function () {
                if (callback != null) {
                    callback();
                }

            }, 300);
        });
    }


});
;

window.CartStore = {
    state: {
        cartItems: [],
        cartId: '',
        cartDto: {},
        encryptedCartId: '',
        transactionId: 0,
        memberId: null,
        cartOwnerName: null,
        transaction: null,
        cartState: window.CartState.LOADING,
        cartProcessing: false,
        cartError: "",
        updateTravelDetails: false,
        isLoading: false,
        previousCartItems: null,
    },

    //this takes in a cart object and repopulates the cart
    repopulateCart: function (cart) {

        if (cart == null) {
            return;
        }

        //we are populating the cart for the first time
        if (this.state.previousCartItems == null) {
            //we store this so we can calculate changes
            this.state.previousCartItems = JSON.parse(JSON.stringify(cart.CartItems));
        }
        else {
            //we store this so we can calculate changes
            this.state.previousCartItems = JSON.parse(JSON.stringify(this.state.cartItems));
        }


        //make sure the cart is empty
        if (this.state.cartItems.length > 0) {
            this.emptyCart();
        }

        //now populate it
        this.addItemsToCart(cart.CartItems, true);
        this.state.cartId = cart.EncryptedCartID;
        this.state.encryptedCartId = cart.EncryptedCartID;
        this.state.transactionId = cart.TransactionID;
        this.state.memberId = cart.MemberID;
        this.state.transaction = cart.Transaction;
        this.state.cartOwnerName = cart.FirstName;
        const dob = moment(cart.DateOfBirth).format('YYYY-MM-DD'); // Date of Birth
        const dobSplitArray = dob.split('-');
        cart.month = Number(dobSplitArray[1]); // month
        cart.year = Number(dobSplitArray[0]); // year
        this.state.cartDto = cart;
    },
    addItemToCart: function (item) {

        var itemToAdd = item;//JSON.parse(JSON.stringify(this.DEFAULT_ITEM));
        itemToAdd = _.merge(itemToAdd, item);


        //we want to add the isDeleted flag here, so that users do not need to worry about this
        itemToAdd.TryDelete = false;

        ////we need to check to see if the item is "stackable", if it is, we should update the quantity
        //if (itemToAdd.stackable) {
        //    var index = _.findIndex(this.state.cartItems, { productId: itemToAdd.productId });
        //    if (index > -1) {
        //        this.state.cartItems[index].TransactionLineItem.Quantity++;
        //        return; //get out here so we dont add a new line item
        //    }
        //}

        ////for dependent items, we want to know if we already have one of these in the cart already.  If this is the case,
        ////we dont want to add it
        //if (itemToAdd.dependentProductId > 0) {
        //    var index = _.findIndex(this.state.cartItems, { ItemID: itemToAdd.ItemID });
        //    if (index > -1) {
        //        return;
        //    }
        //}

        //add the index to the new item so that we can handle add and deletes
        this.state.cartItems.push(itemToAdd);
        itemToAdd.index = this.state.cartItems.length - 1;
        itemToAdd.TransactionLineItem.LineItemSequence = itemToAdd.index + 1;

        //if (dontSendToApi) {
        //    return;
        //} else {
        //    this.sendCartToApi();
        //}
    },
    addItemsToCart: function (items) {
        var self = this;
        items.forEach(function (cartItem) {
            self.addItemToCart(cartItem);
        });

    },
    emptyCart: function () {
        this.state.cartItems.splice(0, this.state.cartItems.length);
    },
    toggleMarkItemForRemoval: function (index) {
        this.state.cartItems[index].TryDelete = !this.state.cartItems[index].TryDelete;
    },
    removeItemFromCart: function (index, success, error) {
        var self = this;
        var item = JSON.parse(JSON.stringify(this.state.cartItems[index]));
        //item.IsLoading = true;
        //this.state.cartItems.splice(index, 1,item);
        //return;

        var req = {
            CartID: this.state.encryptedCartId,
            CartItemID: item.CartItemID,
        };

        self.setCartLoading();
        $.post({
            url: '/api/Cart/deleteitem',
            data: req,
            dataType: 'json',
            success: function (response) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();
                if (response.Status == eResponseStatus.Ok) {
                    self.repopulateCart(response.Cart);
                    if (!!success) {
                        success();
                    }
                    window.GoogleAnalyticsEcommerceEventBus.$emit("REMOVE-FROM-CART");
                }
                else {
                    Common.ShowError("Unexpected error has occurred.");
                }
            },
            error: function (xhr, status, err) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();
                //error
                //window.CartStore.state.cartState = window.CartState.ERROR

                if (!!error) {
                    error();
                }
                else {
                    Common.ShowError("Unexpected error has occurred.");
                }
            }
        });


    },
    removeProductFromCart: function (productId, success, error) {
        var index = _.findIndex(this.state.cartItems, { ItemID: productId });
        this.removeItemFromCart(index, success, error);
    },
    setCartState: function (stateId) {
        this.state.cartState = stateId;
    },
    progressCheckout: function () {

        switch (this.state.cartState) {
            case window.CartState.CHECKOUT_EXTRAS:
                this.state.cartState = window.CartState.CHECKOUT_DETAILS;
                break;
            case window.CartState.CHECKOUT_DETAILS:
                this.state.cartState = window.CartState.CHECKOUT_PAYMENT;
                //this.sendCartToApi();
                break;
            default:
                return;

        }
    },
    retrieveCart: function () {
        var self = this;
        //self.state.cartProcessing = true;
        self.setCartLoading();
        //now that we have all the event handlers, we want to send off a request to see if there is an existing cart
        //window.CartStore.state.cartState = window.CartState.LOADING
        var cartId = '';
        var url = '/api/Cart/GetCart?cartId=';
        try {
            urlCartId = Common.GetUrlParameter('cartId');
            if (typeof (urlCartId) != "undefined") {
                url += encodeURIComponent(urlCartId);
            }

        } catch (err) {

        }

        if (false) {
            window.CartStore.state.cartItems = [{ "CartItemID": 2106, "CartID": 1522, "TransactionLineItemID": 1613543, "ItemID": 0, "CartItemTypeID": 3, "IsDeleted": false, "Referer": null, "RefererType": 0, "RefererUrl": null, "RefererDomain": null, "BookingID": null, "TransactionLineItem": { "TransactionLineItemID": 1613543, "TransactionID": 881779, "StoreID": "298884b9-5051-4409-98bb-1d0d5f86c5ea", "LineItemSequence": 1, "ArrivalDate": null, "DepartureDate": null, "SKU": "35", "InvoiceNumber": null, "Description": "Holiday Perks+ Member - Join", "Quantity": 1, "UnitPrice": 50, "LineDiscountAmount": 0, "DiscountReasonID": null, "ExtendedPrice": 50, "CurrencyCode": "AUD", "CreatedBy": "anonymous", "CreatedDateTime": "2019-11-07T16:06:34.053", "ModifiedBy": "anonymous", "ModifiedDateTime": "2019-11-07T16:06:34.053", "LineItemTypeID": 3, "LineItemStatusID": 106, "ReferralTypeID": null, "LoggedCalculation": null, "ReferenceNumber": null, "CancellationDate": null, "AmountPaid": 50, "BookingID": null, "Booking": null }, "ParkName": null, "ParkTypeID": 0, "DealName": null, "IsMemberOnlyDeal": false, "ProductName": null, "AccommodationType": null, "ParkStateAlias": null, "AdditionalDetails": null, "IsUnavailable": false, "PetFriendly": false, "ParkTermsAndConditionsURL": null, "ParkPetTermsAndConditionsURL": null, "ErrorMessage": null, "TryDelete": false, "index": 0 }, { "CartItemID": 2107, "CartID": 1522, "TransactionLineItemID": 1613544, "ItemID": 0, "CartItemTypeID": 5, "IsDeleted": false, "Referer": null, "RefererType": 0, "RefererUrl": null, "RefererDomain": null, "BookingID": null, "TransactionLineItem": { "TransactionLineItemID": 1613544, "TransactionID": 881779, "StoreID": "298884b9-5051-4409-98bb-1d0d5f86c5ea", "LineItemSequence": 2, "ArrivalDate": null, "DepartureDate": null, "SKU": "discount10", "InvoiceNumber": null, "Description": "Discount for Online Promotion 'Discount 10%'", "Quantity": 1, "UnitPrice": -10, "LineDiscountAmount": null, "DiscountReasonID": null, "ExtendedPrice": -10, "CurrencyCode": "AUD", "CreatedBy": "anonymous", "CreatedDateTime": "2019-11-07T16:07:02.96", "ModifiedBy": "anonymous", "ModifiedDateTime": "2019-11-07T16:07:02.96", "LineItemTypeID": 23, "LineItemStatusID": 134, "ReferralTypeID": null, "LoggedCalculation": null, "ReferenceNumber": "Membership", "CancellationDate": null, "AmountPaid": -10, "BookingID": null, "Booking": null }, "ParkName": null, "ParkTypeID": 0, "DealName": null, "IsMemberOnlyDeal": false, "ProductName": null, "AccommodationType": null, "ParkStateAlias": null, "AdditionalDetails": null, "IsUnavailable": false, "PetFriendly": false, "ParkTermsAndConditionsURL": null, "ParkPetTermsAndConditionsURL": null, "ErrorMessage": null, "TryDelete": false, "index": 1 }];

            window.CartStore.state.cartItems[1].IsMemberOnlyDeal = false;
            window.CartStore.setCartState(window.CartState.EDIT);

            //we want to fire an event so that any listeners can find out
            //that we are ready to be manipulated
            window.CartEventBus.$emit(window.CartEvents.LOADED);
            self.setCartFinishedLoading();
            setTimeout(function () { window.hideLoadingBlob(); }, 1000);
            return;
        }


        $.ajax({
            type: 'GET',
            url: url,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (response) {
                //self.state.cartProcessing = false;
                if (response.Status == window.eResponseStatus.Ok) {
                    window.CartStore.repopulateCart(response.Cart);
                    window.CartStore.setCartState(window.CartState.EDIT);

                    //we want to fire an event so that any listeners can find out
                    //that we are ready to be manipulated
                    window.CartEventBus.$emit(window.CartEvents.LOADED);
                }
                else {
                    //window.CartStore.state.cartState = window.CartState.ERROR
                }
                self.setCartFinishedLoading();




            },
            error: function (xhr, statusText, err) {
                //self.state.cartProcessing = false;
                //window.CartStore.state.cartState = window.CartState.ERROR
                self.setCartFinishedLoading();

            }
        });


    },

    removeMembership: function (success, error) {
        var index = _.findIndex(this.state.cartItems, { CartItemTypeID: window.CartItemType.MEMBERSHIP });

        if (index > -1) {
            this.removeItemFromCart(index, success, error);
        }
    },
    setCartProcessing: function () {
        this.setCartLoading();
        //this.state.cartProcessing = true;
    },
    stopProcessing: function () {
        this.setCartFinishedLoading();
        //this.state.cartProcessing = false;
    },
    setCartError: function (error) {
        this.state.cartError = error;
    },

    openCart: function () {
        //open the cart
        $('#cartModal > span').first().click();
    },
    closeCart: function () {
        //close the cart
        document.getElementById('cartModalWrapper').__vue__.closeModal();
    },
    addBooking: function (item, success, error) {

        var self = this;

        var req = item;

        req.CartID = self.state.encryptedCartId;

        self.setCartLoading();
        $.post({
            url: '/api/Cart/AddBooking',
            data: req,
            dataType: 'json',
            success: function (response) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();

                if (response.Status == eResponseStatus.Ok) {
                    self.repopulateCart(response.Cart);
                    if (!!success) {
                        success();
                    }
                    self.openCart();
                    window.GoogleAnalyticsEcommerceEventBus.$emit("ADD-TO-CART");
                }
                else {
                    //error
                    //window.CartStore.state.cartState = window.CartState.ERROR
                    if (!!error) {
                        if (response.ResponseMessage === "ALLOTMENT_UNAVAILABLE") {
                            error("This accommodation is not available for the continuous period selected.");
                        }
                        else {
                            error();
                        }
                    }
                }
            },
            error: function (xhr, status, err) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();
                //error
                //window.CartStore.state.cartState = window.CartState.ERROR

                if (!!error) {
                    error();
                }
            }
        });

    },
    addProducts: function (items, success, error) {

        var self = this;

        var req = {
            CartID: self.state.encryptedCartId,
            Products: items,
        };


        self.setCartLoading();
        $.post({
            url: '/api/Cart/AddProduct',
            data: req,
            dataType: 'json',
            success: function (response) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();

                if (response.Status == eResponseStatus.Ok) {
                    self.repopulateCart(response.Cart);
                    if (!!success) {
                        success();
                    }
                    self.openCart();
                    window.GoogleAnalyticsEcommerceEventBus.$emit("ADD-TO-CART");
                }
                else {
                    //error
                    //window.CartStore.state.cartState = window.CartState.ERROR
                    if (!!error) {
                        error(response.ResponseMessage);
                    }
                    else {
                        Common.ShowError("Unexpected error has occurred.");
                    }
                }
            },
            error: function (xhr, status, err) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();
                //error
                //window.CartStore.state.cartState = window.CartState.ERROR

                if (!!error) {
                    error();
                }
                else {
                    Common.ShowError("Unexpected error has occurred.");
                }
            }
        });

    },

    addGiftcardPromocodeToCart: function (code, success, error) {

        var self = this;

        var req = {
            CartID: self.state.encryptedCartId,
            Code: code
        };

        self.setCartLoading();
        $.post({
            url: '/api/cart/addgiftcardpromocode',
            data: req,
            dataType: 'json',
            success: function (response) {
                self.setCartFinishedLoading();

                if (response.Status == eResponseStatus.Ok) {
                    self.repopulateCart(response.Cart);
                    if (success) {
                        success();
                    }
                }
                else {
                    if (error) {
                        error(response.ResponseMessage);
                    }
                    else {
                        Common.ShowError("Unexpected error has occurred.");
                    }
                }
            },
            error: function (xhr, status, err) {
                self.setCartFinishedLoading();

   

                switch (xhr.status) {
                    case 409:
                        Common.ShowError("Uh, oh! Too many tries.  Please try again later.");
                        break;
                    case 404:
                        error();
                        break;
                }

            }
        });

    },
    updateProduct: function (item, success, error) {
        var self = this;

        var req = item;
        req.CartID = self.state.encryptedCartId;


        self.setCartLoading();
        $.post({
            url: '/api/Cart/UpdateProduct',
            data: req,
            dataType: 'json',
            success: function (response) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();

                if (response.Status == eResponseStatus.Ok) {
                    self.repopulateCart(response.Cart);
                    if (!!success) {
                        success();
                    }
                    self.openCart();
                    window.GoogleAnalyticsEcommerceEventBus.$emit("UPDATE-CART",item.CartItemID);
                }
                else {
                    //error
                    //window.CartStore.state.cartState = window.CartState.ERROR
                    if (!!error) {
                        error();
                    }
                    else {
                        Common.ShowError("Unexpected error has occurred.");
                    }
                }
            },
            error: function (xhr, status, err) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();
                //error
                //window.CartStore.state.cartState = window.CartState.ERROR

                if (!!error) {
                    error();
                }
                else {
                    Common.ShowError("Unexpected error has occurred.");
                }
            }
        });
    },
    addGiftcards: function (items, success, error) {

        var self = this;

        var req = {
            CartID: self.state.encryptedCartId,
            GiftCards: items,
        };


        self.setCartLoading();
        $.post({
            url: '/api/Cart/AddGiftCards',
            data: req,
            dataType: 'json',
            success: function (response) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();

                if (response.Status == eResponseStatus.Ok) {
                    self.repopulateCart(response.Cart);
                    if (!!success) {
                        success();
                    }
                    self.openCart();
                    window.GoogleAnalyticsEcommerceEventBus.$emit("ADD-TO-CART");
                }
                else {
                    //error
                    //window.CartStore.state.cartState = window.CartState.ERROR
                    if (!!error) {
                        error();
                    }
                    else {
                        Common.ShowError("Unexpected error has occurred.");
                    }
                }
            },
            error: function (xhr, status, err) {
                //self.state.cartProcessing = false;
                self.setCartFinishedLoading();
                //error
                //window.CartStore.state.cartState = window.CartState.ERROR

                if (!!error) {
                    error();
                }
                else {
                    Common.ShowError("Unexpected error has occurred.");
                }
            }
        });

    },
    addMembership: function (success, error) {

        var item = [{
            ItemType: window.CartItemType.MEMBERSHIP
        }];

        this.addProducts(item, success, error);

    },
    addGiftcardPostage: function (success, error) {

        var self = this;
        var req = {};
        req.CartID = self.state.encryptedCartId;

        self.setCartLoading();
        $.post({
            url: '/api/Cart/AddGiftCardPostage',
            data: req,
            dataType: 'json',
            success: function (response) {
                self.setCartFinishedLoading();

                if (response.Status == eResponseStatus.Ok) {
                    self.repopulateCart(response.Cart);
                    if (!!success) {
                        success();
                    }
                }
                else {
                    if (!!error) {
                        error();
                    }
                }
            },
            error: function (xhr, status, err) {
                self.setCartFinishedLoading();

                if (!!error) {
                    error();
                }
            }
        });

    },
    removeGiftcardPostage: function (success, error) {


        var index = _.findIndex(this.state.cartItems, { CartItemTypeID: window.CartItemType.GIFTCARD_POSTAGE_FEE });

        if (index > -1) {
            this.removeItemFromCart(index, success, error);
        }

    },
    setCartLoading: function () {
        this.state.cartProcessing = true;
        $('.c-cart-summary').block({ message: elementBlockUI });
    },
    setCartFinishedLoading: function () {
        $('.c-cart-summary').unblock();
        this.state.cartProcessing = false;
    }

};;

Vue.component('cart-summary', {

    template: "#CART_SUMMARY_TEMPLATE",
    
    /*
     * Initial state of the component's data.
    */
    data: function () {
        return {
            state: window.CartStore.state,
        }
    },
    computed: {
        
        isEmptyCart: function () {
            if (this.hasParks) {
                return false;
            }
            
            if (this.hasExtras) {
                return false;
            }

            return true;
        },

        hasParks: function () {
            return this.parks.length > 0;
        },
        hasReductions: function () {
            return this.reductions.length > 0;
        },
        hasExtras: function () {
            return this.extras.length > 0;
        },
        hasError: function () {
            return this.state.cartState == window.CartState.ERROR;
        },
        isLoading: function () {
            return this.state.cartState == window.CartState.LOADING;
        },
        parks: function () {
            return _.filter(this.state.cartItems, function (item) {
                return item.CartItemTypeID == window.CartItemType.ACCOMMODATION;
            });
        },
        reductions: function () {
            return _.filter(this.state.cartItems, function (item) {
                return item.CartItemTypeID == window.CartItemType.PROMOTION || item.CartItemTypeID == window.CartItemType.GIFTCARD_REDEMPTION;
            });
        },
        extras: function () {
            return _.filter(this.state.cartItems, function (item) {
                return (item.CartItemTypeID == window.CartItemType.MEMBERSHIP || item.CartItemTypeID == window.CartItemType.GIFTCARD || item.CartItemTypeID == window.CartItemType.PRODUCT || item.CartItemTypeID == window.CartItemType.GIFTCARD_POSTAGE_FEE);
            });
        },
        showHeaderCheckout: function () {
            //return (this.state.cartState != window.CartState.NEW && this.state.cartState != window.CartState.EDIT);
            //this should only return true on the checkout page
            return (this.state.cartState == window.CartState.CHECKOUT_EXTRAS || this.state.cartState == window.CartState.CHECKOUT_DETAILS || this.state.cartState == window.CartState.CHECKOUT_PAYMENT) && (this.$mq == "xl" || this.$mq == "lg");
        },
        showHeaderCheckoutComplete: function () {
            //return (this.state.cartState != window.CartState.NEW && this.state.cartState != window.CartState.EDIT);
            //this should only return true on the checkout page
            return (this.state.cartState == window.CartState.PAID);
        },
        mounted: function () {
            var self = this;

            //window.CartEventBus.$on(window.CartEvents.ERROR_LOADING_CART, function () {
            //    self.hasError = true;
            //});
            //window.CartEventBus.$on(window.CartEvents.LOADING_CART, function () {
            //    window.CartStore
            //});

        }

    },
   

});
;
window.GoogleAnalyticsEcommerceEventBus = new Vue();


if (window.featureFlags.BAPI_3113_google_analytics_data_layer_update) {
    Vue.component('google-analytics-ecommerce', {
        mixins: [MIXIN_MEMBERSHIP],
        template: "<div style='display:none'></div>",

        mounted: function () {
            var self = this;

            window.GoogleAnalyticsEcommerceEventBus.$on("ADD-TO-CART", function () {
                var products = self.getCartObjects();

                var gaObject = {
                    'event': 'addToCart',
                    'ecommerce': {
                        'currencyCode': 'AUD',
                        'add': {
                            // 'add' actionFieldObject measures.
                            'actionField': {
                                'list': 'Cart'
                            },
                            'products': products,
                            'memberNumber': '',
                        }
                    }
                };

                var member = window.LoginStore.state.membership;
                if (member != null) {
                    gaObject.ecommerce.add.memberNumber = member.Number;
                }

                // Measure adding a product to a shopping cart by using an 'add' actionFieldObject
                // and a list of productFieldObjects.
                dataLayer.push(gaObject);
            });

            window.GoogleAnalyticsEcommerceEventBus.$on("UPDATE-CART", function (cartItemId) {

                //we need to handle the update product differently
                //this is because the UI updates, so we don't get change to capture the quantity before the change.
                //but we know if must have only changed by 1.
                var index = _.findIndex(window.CartStore.state.cartItems, { CartItemID: cartItemId });
                var item = JSON.parse(JSON.stringify(window.CartStore.state.cartItems[index]));
                item.TransactionLineItem.Quantity = 1;

                var data = self.getCartObject(item);

                var gaObject = {
                    'event': 'addToCart',
                    'ecommerce': {
                        'currencyCode': 'AUD',
                        'add': {
                            // 'add' actionFieldObject measures.
                            'actionField': {
                                'list': 'Cart'
                            },
                            'products': [data]
                        }
                    }
                };

                // Measure adding a product to a shopping cart by using an 'add' actionFieldObject
                // and a list of productFieldObjects.
                dataLayer.push(gaObject);
            });

            window.GoogleAnalyticsEcommerceEventBus.$on("REMOVE-FROM-CART", function () {
                var products = self.getCartObjects();

                var gaObject = {
                    'event': 'removeFromCart',
                    'ecommerce': {
                        'currencyCode': 'AUD',
                        'remove': {
                            // 'remove' actionFieldObject measures.
                            'actionField': {
                                'list': 'Cart'
                            },
                            'products': products
                        }
                    }
                };

                // Measure adding a product to a shopping cart by using an 'add' actionFieldObject
                // and a list of productFieldObjects.
                dataLayer.push(gaObject);
            });

            window.GoogleAnalyticsEcommerceEventBus.$on('START_CHECKOUT', function () { self.startCheckout(); });
            window.GoogleAnalyticsEcommerceEventBus.$on('CHANGE_CHECKOUT_STEP', function (step) { self.changeCheckoutStep(step); });
            window.GoogleAnalyticsEcommerceEventBus.$on('PURCHASE', function () { self.purchase(); });
            window.GoogleAnalyticsEcommerceEventBus.$on('ACCOM_DATE_UPDATE', function (allotmentObj, accomObj) { self.accomDateUpdate(allotmentObj, accomObj); });
            window.GoogleAnalyticsEcommerceEventBus.$on('SAVE_DETAILS_TO_DAL', function (details) { self.saveDetailsToDAL(details); });
            window.GoogleAnalyticsEcommerceEventBus.$on('SAVE_PETINFO_TO_DAL', function (itemValue) { self.savePetInfoToDAL(itemValue); });

        },
        methods: {
            getCartObjects: function () {
                var self = this;
                var items = self.getCartChanges();

                var products = [];
                for (var i = 0; i < items.length; i++) {
                    products.push(this.getCartObject(items[i]));
                }

                return products;

            },

            getCartObject: function (item) {
                var self = this;
                var data = null;
                switch (item.CartItemTypeID) {
                    case window.CartItemType.ACCOMMODATION:
                        data = self.getAccommodationObject(item);
                        break;
                    case window.CartItemType.GIFTCARD:
                        data = self.getGiftcardObject(item);
                        break;
                    case window.CartItemType.MEMBERSHIP:
                        data = self.getMembershipObject(item);
                        break;
                    case window.CartItemType.PRODUCT:
                        data = self.getParkProductObject(item);
                        break;
                    // case window.CartItemType.GIFTCARD_REDEMPTION: 5
                    // case window.CartItemType.GIFTCARD_POSTAGE_FEE: 6
                }

                return data;
            },
            getAccommodationObject: function (item) {

                var arrivalMoment = moment(item.TransactionLineItem.ArrivalDate).startOf('day');
                var departureMoment = moment(item.TransactionLineItem.DepartureDate).startOf('day');



                var accomObj = {
                    'name': item.ProductName,
                    'id': item.CartItemID,
                    'price': item.TransactionLineItem.ExtendedPrice,
                    'brand': item.ParkName,
                    'category': window.EnumText.ParkTypeEnum[item.ParkTypeID],
                    'variant': item.AccommodationType,
                    'quantity': 1,
                    'position': item.index + 1,
                    'dimension1': this.isLoggedIn ? "Signed In" : "Guest",
                    'dimension2': this.membershipLevel,
                    'dimension3': arrivalMoment.format("DD/MM/YYYY") + "-" + departureMoment.format("DD/MM/YYYY"),
                    'metric1': departureMoment.diff(arrivalMoment, 'days'),
                    'promo': {},
                    'guests': '',
                    'price': item.TransactionLineItem.ExtendedPrice,
                    'totalCartCost': this.getCartTotalPrice(),
                    'numberOfItemsInCart': this.getNumberOfItemsInCart()
                };

                if (item.DealName != null && item.DealName.length > 0) {
                    accomObj.promo = {
                        'promoName': item.DealName,
                        'promoDiscount': item.TransactionLineItem.LineDiscountAmount,
                    };
                }

                if (item.TransactionLineItem.Booking.Adults) {
                    accomObj.guests = item.TransactionLineItem.Booking.Adults + ' adults';

                    if (item.TransactionLineItem.Booking.Children) {
                        accomObj.guests += ', ' + item.TransactionLineItem.Booking.Children + ' children';
                    }

                    if (item.TransactionLineItem.Booking.Infants) {
                        accomObj.guests += ', ' + item.TransactionLineItem.Booking.Infants + ' infants';
                    }
                }

                return accomObj;
            },
            getMembershipObject: function (item) {

                return {
                    'name': item.TransactionLineItem.Description,
                    'id': item.CartItemID,
                    'price': item.TransactionLineItem.ExtendedPrice,
                    'brand': 'BIG4',
                    'category': 'Membership',
                    'quantity': 1,
                    'position': item.index + 1,
                    'dimension1': this.isLoggedIn ? "Signed In" : "Guest",
                    'dimension2': this.membershipLevel,
                    'totalCartCost': this.getCartTotalPrice(),
                    'numberOfItemsInCart': this.getNumberOfItemsInCart()
                }

            },
            getGiftcardObject: function (item) {

                return {
                    'name': 'Giftcard',
                    'id': item.CartItemID,
                    'price': item.TransactionLineItem.UnitPrice,
                    'brand': 'BIG4',
                    'category': 'Giftcard',
                    'quantity': item.TransactionLineItem.Quantity,
                    'position': item.index + 1,
                    'dimension1': this.isLoggedIn ? "Signed In" : "Guest",
                    'dimension2': this.membershipLevel,
                    'totalCartCost': this.getCartTotalPrice(),
                    'numberOfItemsInCart': this.getNumberOfItemsInCart()
                }

            },
            getParkProductObject: function (item) {

                return {
                    'name': item.ProductName,
                    'id': item.CartItemID,
                    'price': item.TransactionLineItem.UnitPrice,
                    'brand': item.ParkName,
                    'category': 'In Park Product',
                    'quantity': item.TransactionLineItem.Quantity,
                    'position': item.index + 1,
                    'dimension1': this.isLoggedIn ? "Signed In" : "Guest",
                    'dimension2': this.membershipLevel,
                    'totalCartCost': this.getCartTotalPrice(),
                    'numberOfItemsInCart': this.getNumberOfItemsInCart()
                }

            },
            getNumberOfItemsInCart: function () {
                var items = _.filter(window.CartStore.state.cartItems, function (item) {
                    return item.CartItemTypeID === window.CartItemType.ACCOMMODATION || item.CartItemTypeID === window.CartItemType.GIFTCARD
                        || item.CartItemTypeID === window.CartItemType.MEMBERSHIP || item.CartItemTypeID === window.CartItemType.PRODUCT;
                });

                return items.length;
            },
            getCartChanges: function () {
                var itemsToReturn = [];

                //something was removed
                if (window.CartStore.state.cartItems.length < window.CartStore.state.previousCartItems.length) {

                    //foreach of the items in the previous list
                    for (var i = 0; i < window.CartStore.state.previousCartItems.length; i++) {
                        var matched = false;

                        for (var j = 0; j < window.CartStore.state.cartItems.length; j++) {
                            if (window.CartStore.state.previousCartItems[i].CartItemID == window.CartStore.state.cartItems[j].CartItemID) {
                                matched = true;
                                break;
                            }

                        }

                        if (!matched) {
                            //if we get to here, we didn't find a match
                            itemsToReturn.push(window.CartStore.state.previousCartItems[i]);
                        }
                    }

                }
                else {
                    //something was added
                    if (window.CartStore.state.cartItems.length > window.CartStore.state.previousCartItems.length) {

                        //foreach of the items in the current list
                        for (var i = 0; i < window.CartStore.state.cartItems.length; i++) {

                            var matched = false;
                            for (var j = 0; j < window.CartStore.state.previousCartItems.length; j++) {
                                if (window.CartStore.state.cartItems[i].CartItemID == window.CartStore.state.previousCartItems[j].CartItemID) {
                                    matched = true;
                                    break;
                                }

                            }

                            if (!matched) {
                                //if we get to here, we didn't find a match
                                itemsToReturn.push(window.CartStore.state.cartItems[i]);
                            }
                        }

                    }

                    //quantity change, we always want to check this as part of the add
                    //foreach of the items in the current list
                    for (var i = 0; i < window.CartStore.state.cartItems.length; i++) {

                        for (var j = 0; j < window.CartStore.state.previousCartItems.length; j++) {
                            if (window.CartStore.state.cartItems[i].CartItemID == window.CartStore.state.cartItems[j].CartItemID) {
                                if (window.CartStore.state.cartItems[i].TransactionLineItem.Quantity != window.CartStore.state.previousCartItems[j].TransactionLineItem.Quantity) {

                                    //we want to return the item with the quantity that was added
                                    var item = JSON.parse(JSON.stringify(window.CartStore.state.cartItems[i]));
                                    item.TransactionLineItem.Quantity = window.CartStore.state.cartItems[i].TransactionLineItem.Quantity - window.CartStore.state.previousCartItems[j].TransactionLineItem.Quantity;
                                    itemsToReturn.push(item);
                                }
                            }

                        }
                    }
                }

                return itemsToReturn;

            },
            getCartTotalPrice: function () {
                var items = window.CartStore.state.cartItems;
                var totalPrice = 0;

                for (i = 0; i < items.length; i++) {
                    totalPrice += items[i].TransactionLineItem.ExtendedPrice;
                }

                return totalPrice;
            },
            startCheckout: function () {

                var items = window.CartStore.state.cartItems;
                var dataLayerObj = {
                    'event': 'checkout',
                    'ecommerce': {
                        'checkout': {
                            'actionField': {
                                'step': 1
                            },
                            'products': []
                        }
                    }
                };



                if (items.length > 0) {
                    for (var i = 0; i < items.length; i++) {
                        dataLayerObj.ecommerce.checkout.actionField.revenue += items[i].TransactionLineItem.ExtendedPrice;

                        switch (items[i].CartItemTypeID) {
                            case window.CartItemType.ACCOMMODATION:
                                dataLayerObj.ecommerce.checkout.products.push(this.getAccommodationObject(items[i]));
                                break;

                            case window.CartItemType.GIFTCARD:
                                dataLayerObj.ecommerce.checkout.products.push(this.getGiftcardObject(items[i]));
                                break;

                            case window.CartItemType.MEMBERSHIP:
                                dataLayerObj.ecommerce.checkout.products.push(this.getMembershipObject(items[i]));
                                break;

                            case window.CartItemType.PRODUCT:
                                dataLayerObj.ecommerce.checkout.products.push(this.getParkProductObject(items[i]));
                                break;
                        }
                    }
                }

                dataLayer.push(dataLayerObj);

            },
            changeCheckoutStep: function (step) {

                dataLayer.push({ 'event': 'checkout', 'ecommerce': { 'checkout': { 'actionField': { 'step': step } } } });

            },
            saveDetailsToDAL: function (details) {
                //send Email Address to datalayer
                dataLayer.push({ 'event': 'checkout', 'ecommerce': { 'checkout': { 'actionField': { 'email': details.EmailAddress } } } });
                //send Date of birth to datalayer
                var DOB = new Date(details.year, details.month-1);
                if (DOB instanceof Date && !isNaN(DOB)) {
                    dataLayer.push({ 'event': 'checkout', 'ecommerce': { 'checkout': { 'actionField': { 'DateOfBirth': DOB.toDateString() } } } });
                }

            },
            savePetInfoToDAL: function (itemValue) {
                dataLayer.push({ 'event': 'checkout', 'ecommerce': { 'checkout': { 'actionField': { 'pets': itemValue } } } });

            },
            purchase: function () {


                var giftCardRedemptions = _.filter(window.CartStore.state.cartItems, function (item) {
                    return item.CartItemTypeID === window.CartItemType.GIFTCARD_REDEMPTION;
                });
                var paymentType = '';

                if (window.CheckoutStore.state.paymentType.includes('card')) {
                    paymentType = 'credit/debit card';

                    if (giftCardRedemptions.length > 0) {
                        paymentType += ' + gift card'
                    }
                } else if (window.CheckoutStore.state.paymentType == 'googleapple') {
                    paymentType = 'google/apple pay';

                    if (giftCardRedemptions.length > 0) {
                        paymentType += ' + gift card'
                    }
                } else if (window.CheckoutStore.state.paymentType == 'savedPayment') {
                    paymentType = 'saved payment';

                    if (giftCardRedemptions.length > 0) {
                        paymentType += ' + gift card'
                    }
                } else if (window.CheckoutStore.state.paymentType == 'zipPay') {
                    paymentType = 'Zip Pay';

                    if (giftCardRedemptions.length > 0) {
                        paymentType += ' + gift card'
                    }
                } else if (window.CheckoutStore.state.paymentType !== 'googleapple' && !window.CheckoutStore.state.paymentType.includes('card') && giftCardRedemptions.length) {
                    paymentType += 'gift card'
                }

                var items = window.CartStore.state.cartItems;
                var dataLayerObj = {
                    'event': 'purchase',
                    'ecommerce': {
                        'currencyCode': 'AUD',
                        'purchase': {
                            'actionField': {
                                'id': window.CartStore.state.cartDto.TransactionID,
                                'revenue': 0 // Total transaction value (incl. tax and shipping)
                                //'coupon': 'promotion code',
                            },
                            'products': [],
                            'memberNumber': '',
                            'paymentType': paymentType,
                            'giftCardRedemptionValue': 0
                        }
                    }
                };

                var member = window.LoginStore.state.membership;
                if (member != null) {
                    dataLayerObj.ecommerce.purchase.memberNumber = member.Number;
                }

                //Add gift cards to object
                if (giftCardRedemptions != null && giftCardRedemptions.length > 0) {
                    var totalGiftCardValue = 0;
                    for (i = 0; i < giftCardRedemptions.length; i++) {
                        totalGiftCardValue += giftCardRedemptions[i].TransactionLineItem.AmountPaid;
                    }

                    dataLayerObj.ecommerce.purchase.giftCardRedemptionValue = totalGiftCardValue * -1;
                }



                if (items.length > 0) {
                    for (var i = 0; i < items.length; i++) {
                        dataLayerObj.ecommerce.purchase.actionField.revenue += items[i].TransactionLineItem.ExtendedPrice;

                        switch (items[i].CartItemTypeID) {
                            case window.CartItemType.ACCOMMODATION:
                                dataLayerObj.ecommerce.purchase.products.push(this.getAccommodationObject(items[i]));
                                break;

                            case window.CartItemType.GIFTCARD:
                                dataLayerObj.ecommerce.purchase.products.push(this.getGiftcardObject(items[i]));
                                break;

                            case window.CartItemType.MEMBERSHIP:
                                dataLayerObj.ecommerce.purchase.products.push(this.getMembershipObject(items[i]));
                                break;

                            case window.CartItemType.PRODUCT:
                                dataLayerObj.ecommerce.purchase.products.push(this.getParkProductObject(items[i]));
                                break;
                        }
                    }
                }

                dataLayer.push(dataLayerObj);

                //now we also want to handle the old standard ecommerce data
                //this.standardEcommerce();
            },
            accomDateUpdate: function (allotmentObj, accomObj) {
                if (typeof allotmentObj === 'undefined' || allotmentObj == null) { return; }
                if (typeof allotmentObj.DailyAvailability === 'undefined' || allotmentObj.DailyAvailability == null) { return; }
                if (allotmentObj.DailyAvailability.length == 0) { return; }

                var parkTypeString = '';
                var accomTypeString = '';
                var startDate = new Date(allotmentObj.DailyAvailability[0].Date);
                var endDate = new Date(allotmentObj.DailyAvailability[allotmentObj.DailyAvailability.length - 1].Date);

                if (accomObj.ParkType == Enums.ParkTypeEnum.FCOMClassic) {
                    parkTypeString = 'Classic';
                } else if (accomObj.ParkType == Enums.ParkTypeEnum.FCOMHoliday) {
                    parkTypeString = 'Holiday';
                } else if (accomObj.ParkType == Enums.ParkTypeEnum.FCOMPremier) {
                    parkTypeString = 'Premier';
                } else if (accomObj.ParkType == Enums.ParkTypeEnum.Affiliate) {
                    parkTypeString = 'Affiliate';
                } else if (accomObj.ParkType == Enums.ParkTypeEnum.Legacy) {
                    parkTypeString = 'Legacy';
                }

                if (accomObj.IsCabin !== null) {
                    accomTypeString = accomObj.IsCabin ? 'CABINS' : 'SITES';
                } else {
                    accomTypeString = accomObj.AccommodationType;
                }

                var dataLayerObj = {
                    'event': 'accomDateUpdate',
                    'data': {
                        'parkName': accomObj.ParkName,
                        'parkType': parkTypeString,
                        'accommodation': accomObj.AccommodationName ? accomObj.AccommodationName : accomObj.Name,
                        'accomType': accomTypeString,
                        'bookingDates': startDate.toLocaleDateString() + ' - ' + endDate.toLocaleDateString(),
                        'numberOfNights': allotmentObj.DailyAvailability.length - 1,
                        'available': allotmentObj.IsAvailable,
                    }
                };

                dataLayer.push(dataLayerObj);
            },
            standardEcommerce: function () {
                var items = window.CartStore.state.cartItems;

                var transaction = {
                    'transactionId': window.CartStore.state.cartDto.TransactionID,
                    //'transactionAffiliation': 'payment method',
                    'transactionTotal': 0,
                    'transactionProducts': [],
                    'event': 'standardEcommPurchase'
                };

                if (items.length > 0) {
                    for (var i = 0; i < items.length; i++) {
                        transaction.transactionTotal += items[i].TransactionLineItem.ExtendedPrice;

                        switch (items[i].CartItemTypeID) {
                            case window.CartItemType.ACCOMMODATION:
                                var newItem = {
                                    sku: items[i].ProductName + " (" + items[i].TransactionLineItem.Booking.AccommodationID + ")" + " - $" + items[i].TransactionLineItem.ExtendedPrice,
                                    name: items[i].ParkName,
                                    price: items[i].TransactionLineItem.ExtendedPrice,
                                    quantity: items[i].TransactionLineItem.Quantity
                                };

                                if (items[i].AccommodationType == "Cabins") {
                                    newItem.category = "Cabin - FullAmount";
                                }
                                else {
                                    newItem.category = "Site - FullAmount";
                                }


                                transaction.transactionProducts.push(newItem);
                                break;

                            case window.CartItemType.GIFTCARD:
                                transaction.transactionProducts.push({
                                    sku: "0000-0000-0000",
                                    name: "$" + items[i].TransactionLineItem.UnitPrice + "-Electronic",
                                    category: "GiftCard-Electronic",
                                    price: items[i].TransactionLineItem.UnitPrice,
                                    quantity: items[i].TransactionLineItem.Quantity
                                });
                                break;

                            case window.CartItemType.MEMBERSHIP:
                                transaction.transactionProducts.push({
                                    sku: "0000000",
                                    name: "Holiday Perks+ Member - Join",
                                    category: "Membership",
                                    price: items[i].TransactionLineItem.ExtendedPrice,
                                    quantity: items[i].TransactionLineItem.Quantity
                                });
                                break;

                            case window.CartItemType.PRODUCT:
                                transaction.transactionProducts.push({
                                    sku: items[i].ProductName,
                                    name: items[i].ParkName + " - " + items[i].ProductName,
                                    category: "In Park Product",
                                    price: items[i].TransactionLineItem.UnitPrice,
                                    quantity: items[i].TransactionLineItem.Quantity
                                });
                                break;
                        }


                    }
                }

                dataLayer.push(transaction);
            }
        }
    });
} else {
    Vue.component('google-analytics-ecommerce', {
        mixins: [MIXIN_MEMBERSHIP],
        template: "<div style='display:none'></div>",

        mounted: function () {
            var self = this;

            window.GoogleAnalyticsEcommerceEventBus.$on("ADD-TO-CART", function () {
                var products = self.getCartObjects();


                var gaObject = {
                    'event': 'addToCart',
                    'ecommerce': {
                        'currencyCode': 'AUD',
                        'add': {
                            // 'add' actionFieldObject measures.
                            'actionField': {
                                'list': 'Cart'
                            },
                            'products': products
                        }
                    }
                };

                // Measure adding a product to a shopping cart by using an 'add' actionFieldObject
                // and a list of productFieldObjects.
                dataLayer.push(gaObject);
            });

            window.GoogleAnalyticsEcommerceEventBus.$on("UPDATE-CART", function (cartItemId) {

                //we need to handle the update product differently
                //this is because the UI updates, so we don't get change to capture the quantity before the change.
                //but we know if must have only changed by 1.
                var index = _.findIndex(window.CartStore.state.cartItems, { CartItemID: cartItemId });
                var item = JSON.parse(JSON.stringify(window.CartStore.state.cartItems[index]));
                item.TransactionLineItem.Quantity = 1;

                var data = self.getCartObject(item);

                var gaObject = {
                    'event': 'addToCart',
                    'ecommerce': {
                        'currencyCode': 'AUD',
                        'add': {
                            // 'add' actionFieldObject measures.
                            'actionField': {
                                'list': 'Cart'
                            },
                            'products': [data]
                        }
                    }
                };

                // Measure adding a product to a shopping cart by using an 'add' actionFieldObject
                // and a list of productFieldObjects.
                dataLayer.push(gaObject);
            });

            window.GoogleAnalyticsEcommerceEventBus.$on("REMOVE-FROM-CART", function () {
                var products = self.getCartObjects();

                var gaObject = {
                    'event': 'removeFromCart',
                    'ecommerce': {
                        'currencyCode': 'AUD',
                        'remove': {
                            // 'remove' actionFieldObject measures.
                            'actionField': {
                                'list': 'Cart'
                            },
                            'products': products
                        }
                    }
                };

                // Measure adding a product to a shopping cart by using an 'add' actionFieldObject
                // and a list of productFieldObjects.
                dataLayer.push(gaObject);
            });


            window.GoogleAnalyticsEcommerceEventBus.$on('START_CHECKOUT', function () { self.startCheckout(); });
            window.GoogleAnalyticsEcommerceEventBus.$on('CHANGE_CHECKOUT_STEP', function (step) { self.changeCheckoutStep(step); });
            window.GoogleAnalyticsEcommerceEventBus.$on('PURCHASE', function () { self.purchase(); });
            window.GoogleAnalyticsEcommerceEventBus.$on('SAVE_DETAILS_TO_DAL', function (details) { self.saveDetailsToDAL(details); });
            window.GoogleAnalyticsEcommerceEventBus.$on('SAVE_PETINFO_TO_DAL', function (itemValue) { self.savePetInfoToDAL(itemValue); });

        },
        methods: {
            getCartObjects: function () {
                var self = this;
                var items = self.getCartChanges();

                var products = [];
                for (var i = 0; i < items.length; i++) {
                    products.push(this.getCartObject(items[i]));
                }

                return products;

            },

            getCartObject: function (item) {
                var self = this;
                var data = null;
                switch (item.CartItemTypeID) {
                    case window.CartItemType.ACCOMMODATION:
                        data = self.getAccommodationObject(item);
                        break;
                    case window.CartItemType.GIFTCARD:
                        data = self.getGiftcardObject(item);
                        break;
                    case window.CartItemType.MEMBERSHIP:
                        data = self.getMembershipObject(item);
                        break;
                    case window.CartItemType.PRODUCT:
                        data = self.getParkProductObject(item);
                        break;
                    // case window.CartItemType.GIFTCARD_REDEMPTION: 5
                    // case window.CartItemType.GIFTCARD_POSTAGE_FEE: 6
                }


                return data;
            },
            getAccommodationObject: function (item) {

                var arrivalMoment = moment(item.TransactionLineItem.ArrivalDate).startOf('day');
                var departureMoment = moment(item.TransactionLineItem.DepartureDate).startOf('day');

                return {
                    'name': item.ProductName,
                    'id': item.CartItemID,
                    'price': item.TransactionLineItem.ExtendedPrice,
                    'brand': item.ParkName,
                    'category': window.EnumText.ParkTypeEnum[item.ParkTypeID],
                    'variant': item.AccommodationType,
                    'quantity': 1,
                    'position': item.index + 1,
                    'dimension1': this.isLoggedIn ? "Signed In" : "Guest",
                    'dimension2': this.membershipLevel,
                    'dimension3': arrivalMoment.format("DD/MM/YYYY") + "-" + departureMoment.format("DD/MM/YYYY"),
                    'metric1': departureMoment.diff(arrivalMoment, 'days')
                }
            },
            getMembershipObject: function (item) {

                return {
                    'name': item.TransactionLineItem.Description,
                    'id': item.CartItemID,
                    'price': item.TransactionLineItem.ExtendedPrice,
                    'brand': 'BIG4',
                    'category': 'Membership',
                    'quantity': 1,
                    'position': item.index + 1,
                    'dimension1': this.isLoggedIn ? "Signed In" : "Guest",
                    'dimension2': this.membershipLevel,
                }

            },
            getGiftcardObject: function (item) {

                return {
                    'name': 'Giftcard',
                    'id': item.CartItemID,
                    'price': item.TransactionLineItem.UnitPrice,
                    'brand': 'BIG4',
                    'category': 'Giftcard',
                    'quantity': item.TransactionLineItem.Quantity,
                    'position': item.index + 1,
                    'dimension1': this.isLoggedIn ? "Signed In" : "Guest",
                    'dimension2': this.membershipLevel,
                }

            },
            getParkProductObject: function (item) {

                return {
                    'name': item.ProductName,
                    'id': item.CartItemID,
                    'price': item.TransactionLineItem.UnitPrice,
                    'brand': item.ParkName,
                    'category': 'In Park Product',
                    'quantity': item.TransactionLineItem.Quantity,
                    'position': item.index + 1,
                    'dimension1': this.isLoggedIn ? "Signed In" : "Guest",
                    'dimension2': this.membershipLevel,
                }

            },
            getCartChanges: function () {
                var itemsToReturn = [];

                //something was removed
                if (window.CartStore.state.cartItems.length < window.CartStore.state.previousCartItems.length) {

                    //foreach of the items in the previous list
                    for (var i = 0; i < window.CartStore.state.previousCartItems.length; i++) {
                        var matched = false;

                        for (var j = 0; j < window.CartStore.state.cartItems.length; j++) {
                            if (window.CartStore.state.previousCartItems[i].CartItemID == window.CartStore.state.cartItems[j].CartItemID) {
                                matched = true;
                                break;
                            }

                        }

                        if (!matched) {
                            //if we get to here, we didn't find a match
                            itemsToReturn.push(window.CartStore.state.previousCartItems[i]);
                        }
                    }

                }
                else {
                    //something was added
                    if (window.CartStore.state.cartItems.length > window.CartStore.state.previousCartItems.length) {

                        //foreach of the items in the current list
                        for (var i = 0; i < window.CartStore.state.cartItems.length; i++) {

                            var matched = false;
                            for (var j = 0; j < window.CartStore.state.previousCartItems.length; j++) {
                                if (window.CartStore.state.cartItems[i].CartItemID == window.CartStore.state.previousCartItems[j].CartItemID) {
                                    matched = true;
                                    break;
                                }

                            }

                            if (!matched) {
                                //if we get to here, we didn't find a match
                                itemsToReturn.push(window.CartStore.state.cartItems[i]);
                            }
                        }

                    }

                    //quantity change, we always want to check this as part of the add
                    //foreach of the items in the current list
                    for (var i = 0; i < window.CartStore.state.cartItems.length; i++) {

                        for (var j = 0; j < window.CartStore.state.previousCartItems.length; j++) {
                            if (window.CartStore.state.cartItems[i].CartItemID == window.CartStore.state.cartItems[j].CartItemID) {
                                if (window.CartStore.state.cartItems[i].TransactionLineItem.Quantity != window.CartStore.state.previousCartItems[j].TransactionLineItem.Quantity) {

                                    //we want to return the item with the quantity that was added
                                    var item = JSON.parse(JSON.stringify(window.CartStore.state.cartItems[i]));
                                    item.TransactionLineItem.Quantity = window.CartStore.state.cartItems[i].TransactionLineItem.Quantity - window.CartStore.state.previousCartItems[j].TransactionLineItem.Quantity;
                                    itemsToReturn.push(item);
                                }
                            }

                        }
                    }
                }

                return itemsToReturn;

            },
            startCheckout: function () {

                var items = window.CartStore.state.cartItems;
                var dataLayerObj = {
                    'event': 'checkout',
                    'ecommerce': {
                        'checkout': {
                            'actionField': {
                                'step': 1
                            },
                            'products': []
                        }
                    }
                };



                if (items.length > 0) {
                    for (var i = 0; i < items.length; i++) {
                        dataLayerObj.ecommerce.checkout.actionField.revenue += items[i].TransactionLineItem.ExtendedPrice;

                        switch (items[i].CartItemTypeID) {
                            case window.CartItemType.ACCOMMODATION:
                                dataLayerObj.ecommerce.checkout.products.push(this.getAccommodationObject(items[i]));
                                break;

                            case window.CartItemType.GIFTCARD:
                                dataLayerObj.ecommerce.checkout.products.push(this.getGiftcardObject(items[i]));
                                break;

                            case window.CartItemType.MEMBERSHIP:
                                dataLayerObj.ecommerce.checkout.products.push(this.getMembershipObject(items[i]));
                                break;

                            case window.CartItemType.PRODUCT:
                                dataLayerObj.ecommerce.checkout.products.push(this.getParkProductObject(items[i]));
                                break;
                        }
                    }
                }

                dataLayer.push(dataLayerObj);

            },
            changeCheckoutStep: function (step) {

                dataLayer.push({ 'event': 'checkout', 'ecommerce': { 'checkout': { 'actionField': { 'step': step } } } });

            },
            saveDetailsToDAL: function (details) {
                dataLayer.push({ 'event': 'checkout', 'ecommerce': { 'checkout': { 'actionField': { 'email': details.EmailAddress } } } });

            },
            savePetInfoToDAL: function (itemValue) {
                dataLayer.push({ 'event': 'checkout', 'ecommerce': { 'checkout': { 'actionField': { 'pets': itemValue } } } });

            },

            purchase: function () {

                var items = window.CartStore.state.cartItems;
                var dataLayerObj = {
                    'event': 'purchase',
                    'ecommerce': {
                        'currencyCode': 'AUD',
                        'purchase': {
                            'actionField': {
                                'id': window.CartStore.state.cartDto.TransactionID,
                                'revenue': 0 // Total transaction value (incl. tax and shipping)
                                //'coupon': 'promotion code',
                            },
                            'products': []
                        }
                    }
                };



                if (items.length > 0) {
                    for (var i = 0; i < items.length; i++) {
                        dataLayerObj.ecommerce.purchase.actionField.revenue += items[i].TransactionLineItem.ExtendedPrice;

                        switch (items[i].CartItemTypeID) {
                            case window.CartItemType.ACCOMMODATION:
                                dataLayerObj.ecommerce.purchase.products.push(this.getAccommodationObject(items[i]));
                                break;

                            case window.CartItemType.GIFTCARD:
                                dataLayerObj.ecommerce.purchase.products.push(this.getGiftcardObject(items[i]));
                                break;

                            case window.CartItemType.MEMBERSHIP:
                                dataLayerObj.ecommerce.purchase.products.push(this.getMembershipObject(items[i]));
                                break;

                            case window.CartItemType.PRODUCT:
                                dataLayerObj.ecommerce.purchase.products.push(this.getParkProductObject(items[i]));
                                break;
                        }
                    }
                }

                dataLayer.push(dataLayerObj);

                //now we also want to handle the old standard ecommerce data
                //this.standardEcommerce();
            },
            standardEcommerce: function () {
                var items = window.CartStore.state.cartItems;

                var transaction = {
                    'transactionId': window.CartStore.state.cartDto.TransactionID,
                    //'transactionAffiliation': 'payment method',
                    'transactionTotal': 0,
                    'transactionProducts': [],
                    'event': 'standardEcommPurchase'
                };

                if (items.length > 0) {
                    for (var i = 0; i < items.length; i++) {
                        transaction.transactionTotal += items[i].TransactionLineItem.ExtendedPrice;

                        switch (items[i].CartItemTypeID) {
                            case window.CartItemType.ACCOMMODATION:
                                var newItem = {
                                    sku: items[i].ProductName + " (" + items[i].TransactionLineItem.Booking.AccommodationID + ")" + " - $" + items[i].TransactionLineItem.ExtendedPrice,
                                    name: items[i].ParkName,
                                    price: items[i].TransactionLineItem.ExtendedPrice,
                                    quantity: items[i].TransactionLineItem.Quantity
                                };

                                if (items[i].AccommodationType == "Cabins") {
                                    newItem.category = "Cabin - FullAmount";
                                }
                                else {
                                    newItem.category = "Site - FullAmount";
                                }


                                transaction.transactionProducts.push(newItem);
                                break;

                            case window.CartItemType.GIFTCARD:
                                transaction.transactionProducts.push({
                                    sku: "0000-0000-0000",
                                    name: "$" + items[i].TransactionLineItem.UnitPrice + "-Electronic",
                                    category: "GiftCard-Electronic",
                                    price: items[i].TransactionLineItem.UnitPrice,
                                    quantity: items[i].TransactionLineItem.Quantity
                                });
                                break;

                            case window.CartItemType.MEMBERSHIP:
                                transaction.transactionProducts.push({
                                    sku: "0000000",
                                    name: "Holiday Perks+ Member - Join",
                                    category: "Membership",
                                    price: items[i].TransactionLineItem.ExtendedPrice,
                                    quantity: items[i].TransactionLineItem.Quantity
                                });
                                break;

                            case window.CartItemType.PRODUCT:
                                transaction.transactionProducts.push({
                                    sku: items[i].ProductName,
                                    name: items[i].ParkName + " - " + items[i].ProductName,
                                    category: "In Park Product",
                                    price: items[i].TransactionLineItem.UnitPrice,
                                    quantity: items[i].TransactionLineItem.Quantity
                                });
                                break;
                        }


                    }
                }

                dataLayer.push(transaction);
            }
        }
    });
}
;
Vue.component('sign-in-wrapper-cart', {
    data: function () {
        return {
            email: "",
            password: "",
            errorMessage: "",
            isLoading: false,

        };
    },
    methods: {
        submit: function () {

            var self = this;

            this.pristine = new Pristine(this.$el, {
                classTo: "c-field",
                errorClass: 'has-error',
                successClass: 'is-success',
                errorTextParent: 'c-input',
                errorTextClass: 'c-field__error'
            });

            var valid = this.pristine.validate();

            if (valid) {
                var loginRequest = {
                    Username: self.email,
                    Password: self.password,
                }

                self.isLoading = true;
                window.LoginEventBus.$emit(window.LoginEvents.PERFORM_LOGIN, loginRequest, function () {
                    window.location.href = "/checkout";
                });
            }

        }
    },
    mounted: function () {
        var self = this;

       

        window.LoginEventBus.$on(window.LoginEvents.AUTHENTICATION_FAILURE, function (payload) {
            Common.ShowError(payload);
            self.isLoading = false;
        });


    }

    //created() {
    //    alert("mount");
    //},
});;
Vue.component('accommodation-item', {
    props: ['item'],
    mixins:[MIXIN_MEMBERSHIP],
    template: "#CART_ITEM_ACCOMMODATION_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {

        }
    },
    computed: {
        dateFrom: function () {
            if (window.CheckoutStore != undefined)
            {
                if (window.CheckoutStore.state.bookingDates.startDate == null || moment(this.item.TransactionLineItem.ArrivalDate).isBefore(window.CheckoutStore.state.bookingDates.startDate))
                {
                    window.CheckoutStore.state.bookingDates.startDate = moment(this.item.TransactionLineItem.ArrivalDate);
                    window.CheckoutStore.state.bookingDates.parkID = this.item.TransactionLineItem.Booking.ParkID;
                }
            }
            return moment(this.item.TransactionLineItem.ArrivalDate).format('DD MMM YYYY')
        },
        dateTo: function () {
            if (window.CheckoutStore != undefined) {
                if (window.CheckoutStore.state.bookingDates.endDate == null || moment(this.item.TransactionLineItem.DepartureDate).isBefore(window.CheckoutStore.state.bookingDates.endDate))
                {
                    window.CheckoutStore.state.bookingDates.endDate = moment(this.item.TransactionLineItem.DepartureDate);
                }
            }
            return moment(this.item.TransactionLineItem.DepartureDate).format('DD MMM YYYY')
        },
        numberOfNights: function () {
            var toDate = moment(this.item.TransactionLineItem.DepartureDate).startOf('day');
            var fromDate = moment(this.item.TransactionLineItem.ArrivalDate).startOf('day');

            var totalDays = toDate.diff(fromDate, 'day');
            return totalDays;

        },
        hasDeal: function () {
            return this.item.TransactionLineItem.Booking.SpecialOfferID > 0;
        },
        memberName: function () {
            if (this.hasMemberDiscount) {
                if (this.item.TransactionLineItem.Booking.IsPrimaryBookingForCartOwner) {
                    if (window.CheckoutStore) {
                        var result = (window.CheckoutStore.state.details.FirstName + " " + window.CheckoutStore.state.details.LastName).trim();
                        if (result != 'null null') {
                            return result;
                        } else {
                            return '';
                        }
                    }
                    else {
                        return '';
                    }
                }
                else if (this.item.TransactionLineItem.Booking.BookingParty != null) {
                    if (this.item.TransactionLineItem.Booking.BookingParty.FirstName) {
                        var result = (this.item.TransactionLineItem.Booking.BookingParty.FirstName + " " + this.item.TransactionLineItem.Booking.BookingParty.LastName).trim();
                        if (result != 'null null') {
                            return result;
                        } else
                        {
                            return '';
                        }
                    }
                }
            }
        },
        discountLogo: function () {
            if (this.hasMemberDiscount) {
                if (this.item.TransactionLineItem.Booking.BookingParty != null) {
                    if (this.item.TransactionLineItem.Booking.BookingParty.MemberNo) {
                        return this.getLogoByMembershipLevel(this.item.TransactionLineItem.Booking.BookingParty.MembershipLevel);
                    }
                }
                return this.membershipLogo;
            }
        },
        loggedIn: function ()
        {
            return this.isLoggedIn;
        },
        getMembershipPricingClass: function (level) {

            if (this.hasMemberDiscount) {
                if (this.item.TransactionLineItem.Booking.BookingParty != null) {
                    if (this.item.TransactionLineItem.Booking.BookingParty.MemberNo) {

                        switch (this.item.TransactionLineItem.Booking.BookingParty.MembershipLevel) {

                            case 9 /*perks plus*/:
                                return "c-pricing__membership--plus";
                            case 8 /*perks*/:
                                return "c-pricing__membership--holiday";
                            case 10 /*viperks*/:
                            case 2 /*staff*/:
                                return "c-pricing__membership--vip";
                        }
                    }
                }
                else {
                    if (this.isVipPerksMember) {
                        return "c-pricing__membership--vip"; 
                    }
                }

                return "c-pricing__membership--plus";

            }

            
        },
        isMemberDeal: function () {
            //if (this.hasDeal) {
            //    return this.item.deal.membershipType;
            //}

            return this.item.IsMemberOnlyDeal;
        },
        hasMemberDiscount: function () {
            //if (window.CheckoutStore) {
            //    if (window.CheckoutStore.state.checkoutState == window.CheckoutState.PAYMENT) {
                    //if there is a discount associated with the accommodation, there must be a member discount
                    if (this.item.TransactionLineItem.LineDiscountAmount > 0) {
                        return true;
                    }
            //    }
            //}
        },

        guests: function () {
            var guestString = "";

            if (this.item.TransactionLineItem.Booking.Adults > 0) {
                guestString += ", " + this.item.TransactionLineItem.Booking.Adults + " adults";
            }
            if (this.item.TransactionLineItem.Booking.Children > 0) {
                guestString += ", " + this.item.TransactionLineItem.Booking.Children + " children";
            }
            if (this.item.TransactionLineItem.Booking.Infants > 0) {
                guestString += ", " + this.item.TransactionLineItem.Booking.Infants + " infants";
            }

            if (guestString.length > 0) {
                if (guestString.startsWith(', ')) {
                    guestString = guestString.substring(2);
                }
            }

            return guestString;

        }


    },


});
;
Vue.component('cart-line-item', {
    props: ['item'],
    template: "#CART_ITEM_TEMPLATE",

    computed: {
        CartItemType: function () {
            return window.CartItemType;
        }

    }
});
;
Vue.component('freight-line-item', {
    props: ['item'],
    template: "#CART_ITEM_FREIGHT_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {

        }
    },
    computed: {
        price: function () {
            return Math.abs(this.item.TransactionLineItem.ExtendedPrice);
        }


    },
    methods: {
    },

});
;
Vue.component('giftcard-line-item', {
    props: ['item'],
    template: "#CART_ITEM_GIFT_CARD_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {
        }
    },
    computed: {
        subtotal: function () {
            return this.item.TransactionLineItem.ExtendedPrice;
        },
        hasMultipleInCart: function () {
            return this.item.TransactionLineItem.Quantity > 1;
        },
        unitPrice: function () {
            return this.item.TransactionLineItem.UnitPrice;
        },

    },
    methods: {
    },
    mounted: function () {
        var self = this;

        this.$refs.input.$on('onInputNumberChange', function (value) {

            if (value == self.item.TransactionLineItem.Quantity) {
                return;
            }

            var req = {
                CartItemID: self.item.CartItemID,
                Quantity: value - self.item.TransactionLineItem.Quantity
            }

            self.item.TransactionLineItem.Quantity = value;

            window.CartEventBus.$emit(
                window.CartEvents.UPDATE_PRODUCT,
                req,
                function () {
                },
                function () {
                }
            );
        });

    }

});
;
Vue.component('giftcard-redemption-line-item', {
    props: ['item'],
    template: "#CART_ITEM_GIFTCARD_REDEMPTION_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {

        }
    },
    computed: {
        price: function () {
            return Math.abs(this.item.TransactionLineItem.AmountPaid);
        }


    },
    methods: {
    },

});
;
Vue.component('loading-line-item', {
    props: ['loading-line-item'],
    template: "#CART_ITEM_LOADING_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {

        }
    },
    

});
;
Vue.component('membership-line-item', {
    props: ['item'],
    template: "#CART_ITEM_MEMBERSHIP_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {
        }
    },
    computed: {
        subtotal: function () {
            return this.item.TransactionLineItem.UnitPrice;
        },
        physicalMemberCard: function ()
        {
            if (window.CheckoutStore != undefined) {
                return (window.CheckoutStore.state.createAccount.PhysicalMemberCard.toString() == "true");
            }

            return false;
        },
        checkoutLineItem: function ()
        {
            if (window.CheckoutStore != undefined)
            {
                return window.CheckoutStore.state.checkoutState > 1
            }

            return false;
        }


    },
    methods: {
    },

});
;
Vue.component('product-line-item', {
    props: ['item'],
    template: "#CART_ITEM_PRODUCT_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {
        }
    },
    computed: {
        subtotal: function () {
            return this.item.TransactionLineItem.ExtendedPrice;
        },
        hasMultipleInCart: function () {
            return this.item.TransactionLineItem.Quantity > 1;
        },
        unitPrice: function () {
            return this.item.TransactionLineItem.UnitPrice;
        },


    },
    methods: {
    },
    mounted: function () {
        var self = this;

        this.$refs.input.$on('onInputNumberChange', function (value) {

            if (value == self.item.TransactionLineItem.Quantity) {
                return;
            }

            var req = {
                CartItemID: self.item.CartItemID,
                Quantity: value - self.item.TransactionLineItem.Quantity
            }

            self.item.TransactionLineItem.Quantity = value;

            window.CartEventBus.$emit(
                window.CartEvents.UPDATE_PRODUCT,
                req,
                function () {
                },
                function () {
                }
            );
        });
        
    },
    updated: function () {
        this.$refs.input.quantity = this.item.TransactionLineItem.Quantity;
    }

});
;
Vue.component('promo-code-line-item', {
    props: ['item'],
    template: "#CART_ITEM_PROMO_CODE_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {

        }
    },
    computed: {
        price: function () {
            return Math.abs(this.item.TransactionLineItem.ExtendedPrice);
        }


    },
    methods: {
    },

});
;
Vue.component('remove-from-cart', {
    props: ["index"],
    template: "#CART_ITEM_REMOVE_TEMPLATE",

    data: function () {
        return {
            state: window.CartStore.state
        }
    },
    computed: {
        canDelete: function () {
            
            if (this.state.cartState == window.CartState.EDIT) {
                return true;
            }
            if (this.state.cartState == window.CartState.CHECKOUT_EXTRAS) {
                return true;
            }
            if (this.state.cartState == window.CartState.CHECKOUT_DETAILS) {
                return true;
            }

            return false;
        }
    },
    methods: {
        markItemForRemoval:function(index) {
            window.CartStore.toggleMarkItemForRemoval(index);
        }
    },

});
;
Vue.component('unavailable-line-item', {
    props: ['item'],
    template: "#CART_ITEM_UNAVAILABLE_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {

        }
    },
    methods: {
        removeItemFromCart: function () {
            window.CartStore.removeItemFromCart(this.item.index);
        },
    }
    

});
;
Vue.component('deal-card', {
    props: ["deal", "small-card"],
    mixins: [MIXIN_SEARCH_SAVED_SEARCHES],
    template: "#DEAL_CARD_TEMPLATE",
    data: function () {
        return {
            useNewPerkLogo: window.featureFlags.BAPI_4016_deals_page_rearrangement,
        }
    },
    computed: {
        memberOnly: function () {
            return false;
        },
        endDate: function () {
            return moment(this.deal.ToDate).format("DD MMMM YY");
        },
        startDate: function () {
            return moment(this.deal.FromDate).format("DD MMMM YY");
        },
        isSmallCard: function ()
        {
            return this.$props.smallCard;
        }
    },
    methods: {
        GoToUrl: function () {
            this.UpdateCookie({
                url: this.deal.Url,
                title: this.deal.DealName,
                icon: 'deal'
            });

            window.location.href = this.deal.Url;
        }
    },
});;
Vue.component('deal-fine-print-toggle', {
    props: {
        finePrintClicked:
        {
            default: false
        },
        conditions:
        {
            default: "",
        },
        shortDescription:
        {
            default: "",
        }
    },
    mixins: [MIXIN_TOGGLE],
    computed:
    {
        FinePrintExpanded: function ()
        {
            return this.finePrintClicked;
        },
        HasConditions: function ()
        {
            return (this.conditions != null && this.conditions.length != 0);
        },
        HasShortDescription: function ()
        {
            return (this.shortDescription != "" && this.shortDescription != null);
        },
    },
    methods:
    {
        Conditions: function ()
        {
            //TW: We check the pms results conditions object and short description, 
            //and return either or both as part of an array to be shown on the front end

            var self = this;
            var allConditions = [];

            if (self.HasConditions) {
                var conditionString = "";
                for (var i = 0; i < self.conditions.length; i++)
                {
                    if (i == (self.conditions.length - 1)) {
                        conditionString += self.conditions[i];
                    }
                    else
                    {
                        conditionString += self.conditions[i] + " / ";
                    }
                }
                allConditions.push(conditionString);

                if (self.HasShortDescription)
                {
                    allConditions.push(self.shortDescription);
                }
                return allConditions;
            } else if (self.HasShortDescription)
            {
                allConditions.push(self.shortDescription);
                return allConditions;
            }
            else return "";
        }
    },
    mounted: function()
    {

    }
});;
Vue.component("deal-map", {
    template: "#DEAL_MAP_TEMPLATE",
    props: ["deals"],
    watch: {
        deals: function () {
            this.generateDealMap();
        }
    },
    methods:
    {
        init: function () {
            if (this.deals != undefined && this.deals.length > 0) {
                new AzureMapWithClusteredDealMarkers('dealMap', deals);
            }
        },
        addDeals: function () {
            //Takes previously generated map and adds new markers based on search results

            var dealResults = window.DealSearchStore.state.AllDealResults;
            var searchLatLngBounds = new google.maps.LatLngBounds();

            //used for map boundary and zoom
            var googleLatLng = [];

            for (var i = 0; i < dealResults.length; i++) {
                try {
                    if (dealResults[i] && dealResults[i].ParkLatitude && dealResults[i].ParkLongitude) {

                        if (!dealResults[i].Rating) {
                            dealResults[i].Rating = [{ Rating: 0 }];
                        }

                        var park = { lat: dealResults[i].ParkLatitude, lng: dealResults[i].ParkLongitude };
                        googleLatLng.push(
                            new google.maps.LatLng(dealResults[i].ParkLatitude, dealResults[i].ParkLongitude)
                        );


                        //TW: Custom map marker icon svg information
                        var icon =
                        {
                            path: "M16 32c7.6-8.2 11.8-13.5 11.8-20.1s-5.3-11.9-11.8-11.9-11.8 5.3-11.8 11.9 4.1 11.9 11.8 20.1zM16 6.7c2.8 0 5.1 2.3 5.1 5.1s-2.3 5.1-5.1 5.1-5.1-2.3-5.1-5.1 2.3-5.1 5.1-5.1z",
                            fillColor: "#ee4b53",
                            fillOpacity: 1.0,
                            anchor: new google.maps.Point(16, 32),
                            strokeWeight: 0,
                            scale: 1
                        }

                        var marker = new google.maps.Marker({
                            position: park,
                            map: window.dealMap,
                            title: dealResults[i].ParkName,
                            icon: icon,
                            review: dealResults[i].Rating[0].Rating * 2,
                            typeID: dealResults[i].ParkTypeID,
                            image: dealResults[i].ImageUrl,
                            page: dealResults[i].DealsPageUrl,
                        });

                        google.maps.event.addListener(marker, 'click', function () {

                            var imgString = "";
                            var reviewString = "";
                            var parkBadgeString = "";

                            //TW: switch for generating park badge based off of type
                            switch (this.typeID) {
                                case (window.Enums.ParkTypeEnum["Affiliate"]):
                                    parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-bullet-rounded c-icon--tertiary-accent"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="227" height="32" viewBox="0 0 227 32"><title>badge-bullet-rounded</title> <path d="M-0.012 3.563c0-4.874 69.747-2.011 98.196-2.011s105.767 2.011 115.202 2.011c9.437 0 29.334 27.599-11.15 27.599-40.483 0-169.104 0.273-185.676 0s-16.572-3.135-16.572-27.599z"></path></svg></span></div> <p class="c-badge__label">Affiliate</p></span></div>'
                                    break;
                                case (window.Enums.ParkTypeEnum["FCOMHoliday"]):
                                    parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-3 c-icon--primary"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="136" height="32" viewBox="0 0 136 32"><title>badge-holiday</title> <path d="M0.879 2.702c1.916-4.48 35.716-2.037 42.326-2.037s67.99 0.646 78.154 0.646c10.165 0 31.658 29.085-11.946 29.085-43.605 0-67.97 1.604-90.122 1.604-22.151 0-18.413-12.376-18.413-29.298z"></path></svg></span></div> <p class="c-badge__label">Holiday</p></span></div>'
                                    break;
                                case (window.Enums.ParkTypeEnum["FCOMClassic"]):
                                    parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-1 c-icon--callout-variant-two"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="132" height="32" viewBox="0 0 132 32"><title>badge-trapezoid-1</title> <path d="M0.077 0.649c27.028-0.555 38.893 0 68.8 0s56.662 2.811 55.373 2.811c-1.289 0 26.849 26.363-15.713 26.363-42.559 0-72.196 1.774-91.23 1.774s-17.322-4.022-17.231-30.948z"></path></svg></span></div> <p class="c-badge__label">Classic</p></span></div>'
                                    break;
                                case (window.Enums.ParkTypeEnum["FCOMPremier"]):
                                    parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-2 c-icon--callout-variant-one"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="135" height="32" viewBox="0 0 135 32"><title>badge-trapezoid-2</title> <path d="M0.031 2.025c17.082-1.098 27.529-1.496 41.797-1.496 14.267 0 67.371-0.268 80.033 4.578 12.665 4.845 27.686 26.365-16.198 26.365h-87.823c-19.403 0-17.809-8.562-17.809-29.448z"></path></svg></span></div> <p class="c-badge__label">Premier</p></span></div>';
                                    break;
                                case (window.Enums.ParkTypeEnum["Legacy"]):
                                    break;

                            }

                            if (this.image != null) {
                                imgString = '<img style="width:100%" srcset="' + this.image + ' 300w" sizes="(min-width: 1024px) 20vw,(min-width: 768px) 30vw,30vw" src="' + this.image + '" alt="">'
                            } else {
                                imgString = '<img srcset="https://placehold.it/280x158 280w,https://placehold.it/300x169 300w,https://placehold.it/300x169 300w" sizes="(min-width: 1024px) 20vw,(min-width: 768px) 30vw,30vw" src="https://placehold.it/300x169" alt="">'
                            }

                            if (this.review != null && this.review > 0) {
                                reviewString = '<div class="c-ratings"><span><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns: xlink="http://www.w3.org/1999/xlink" width="30" height="32" viewBox="0 0 30 32" class="svg-defs" style="position: absolute; width: 0px; height: 0px;"><clipPath id="star"><path d="M29.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3\
                                                c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.3,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6\
                                                c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C0.1,11.5,0,11.2,0,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C14.2,0.2,14.5,0,14.9,0s0.6,0.2,0.9,0.7	l4,8.1l9,1.3C29.4,10.3,29.7,10.5,29.7,11z"></path>\
                                                <path d="M64.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	\
                                                c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C35.1,11.5,35,11.2,35,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C49.2,0.2,49.5,0,49.9,0	s0.6,0.2,0.9,0.7l4,8.1l9,1.3C64.4,10.3,64.7,10.5,64.7,11z"></path>\
                                                <path d="M99.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C70.1,11.5,70,11.2,70,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C84.2,0.2,84.5,0,84.9,0\
                                                c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C99.4,10.3,99.7,10.5,99.7,11z"></path><path d="M134.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	\
                                                c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C134.4,10.3,134.7,10.5,134.7,11z"></path><path d="M169.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	\
                                                c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3s-0.2-0.4-0.2-0.6c0-0.1,0-0.2,0-0.4	l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7s0.6,0.2,0.9,0.7l4,8.1l9,1.3	C169.4,10.3,169.7,10.5,169.7,11z"></path></clipPath><clipPath id="star-empty">\
                                                <path d="M29.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.3,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C0.1,11.5,0,11.2,0,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C14.2,0.2,14.5,0,14.9,0s0.6,0.2,0.9,0.7	l4,8.1l9,1.3C29.4,10.3,29.7,10.5,29.7,11z"></path>\
                                                <path d="M64.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C35.1,11.5,35,11.2,35,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C49.2,0.2,49.5,0,49.9,0	s0.6,0.2,0.9,0.7l4,8.1l9,1.3C64.4,10.3,64.7,10.5,64.7,11z"></path>\
                                                <path d="M99.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C70.1,11.5,70,11.2,70,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C84.2,0.2,84.5,0,84.9,0	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C99.4,10.3,99.7,10.5,99.7,11z"></path>\
                                                <path d="M134.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C134.4,10.3,134.7,10.5,134.7,11z"></path>\
                                                <path d="M169.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3s-0.2-0.4-0.2-0.6c0-0.1,0-0.2,0-0.4	l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7s0.6,0.2,0.9,0.7l4,8.1l9,1.3	C169.4,10.3,169.7,10.5,169.7,11z"></path></clipPath><rect id="rating" width="120" height="30" clip-path="url(#star)"></rect></svg>\
                                                <span class="rating-eg"><svg height="12px" viewBox="0 0 170 30" data-rating="1.2" class="rating"><rect x="0" y="0" width="100%" height="100%" clip-path="url(#star-empty)" class="bg-rect" style="fill: rgb(236, 236, 236);"></rect><rect x="0" y="0" width="'+ this.review * 10 + '%" height="100%" clip-path="url(#star)" class="rating-rect" style="fill: rgb(55, 55, 55);"></rect></svg></span></span> <strong class="u-p4">' + Math.round(this.review * 10) / 10 + '/10</strong></div>'
                                    ;
                            } else {
                                reviewString = '<strong class="u-p4" style="padding-left: 10px;">No reviews yet</strong>';
                            }

                            //TW: This is the html that will generate the park card structure for the google maps infowindow.
                            //We pass in the above generated strings for images and park badge. We also do calculations for ratings here
                            var contentString = '<div class="infoWindow">\
                                 <div class="styleguide-maps" style="background-image: ' + ' " data-component="location-map-container" data-component-context="Location Pages">\
                                 <div class="styleguide-maps__card d-none d-md-block">\
                                <div class="styleguide-maps__card d-none d-md-block"><div data-component="park-card" data-component-context="map" data-component-label="BIG4 Beacon Resort" class="c-card c-card--primary c-card--popup"><div class="c-card__gallery">'
                                + '<a href = "' + this.page + '" class="c-card__img-wrapper"> '
                                + imgString
                                + '</a>'
                                + parkBadgeString
                                + '</div>'
                                + '<div class="c-card__body"><h3 class="u-h6 c-card__title"><a href="' + this.page + '">'
                                + this.title + '</a ></h3 >'
                                + reviewString
                                + '</div>\
                                </div>\
                               </div>';
                            window.dealMapInfowindow.setContent(contentString);
                            window.dealMapInfowindow.open(window.dealMap, this);
                        });
                    }
                } catch(ex) {
                    console.log('Unable to add marker to map for deal [' + dealResults[i].DealName + ']');
                    console.log(ex);
                }


            }

            if (googleLatLng.length > 0) {
                //TW: Fits the map zoom around the markers by default
                for (var i = 0; i < googleLatLng.length; i++) {
                    searchLatLngBounds.extend(googleLatLng[i]);
                }
                window.dealMap.fitBounds(searchLatLngBounds);
            }
        },
        generateDealMap: function () {
            var dealResults = window.DealSearchStore.state.AllDealResults;
            var parkResults = [];

            for (var i = 0; i < dealResults.length; i++) {
                try {
                    if (dealResults[i] && dealResults[i].ParkLatitude && dealResults[i].ParkLongitude) {

                        if (!dealResults[i].Rating) {
                            dealResults[i].Rating = [{ Rating: 0 }];
                        }

                        if (parkResults.filter(function (x) { return x.ParkName == dealResults[i].ParkName }).length === 0) {
                            var newPark = {
                                Latitude: dealResults[i].ParkLatitude,
                                Longitude: dealResults[i].ParkLongitude,
                                ParkName: dealResults[i].ParkName,
                                ReviewRating: dealResults[i].Rating[0].Rating * 2,
                                ParkTypeID: dealResults[i].ParkTypeID,
                                Images: [{ MapsImageUrl: dealResults[i].ImageUrl }],
                                Url: dealResults[i].DealsPageUrl,
                            };

                            parkResults.push(newPark);
                        }
                    }
                } catch (ex) {
                    console.log('Unable to add marker to map for deal [' + dealResults[i].DealName + ']');
                    console.log(ex);
                }
            }

            if (parkResults.length > 0) {
                new AzureMapWithClusteredParkMarkers('dealMap', parkResults, false, 'big4-red');
            }
        }
    },
    mounted: function () {
        this.init();
    }
});;
window.DealSearchEventBus = new Vue();

;

Vue.component('deal-search-handler', {

    template: "<div style='display:none'></div>",
    data: function () {
        return {
            store: window.DealSearchStore
        }
    },
    methods: {
        setSearchLoading:function() {
            this.store.state.PanelLoading = true;
        },
        setSearchFinishedLoading: function () {
            this.store.state.PanelLoading = false;
        },
        updateDealSearch: function (results)
        {
            var self = this;

            if (self.store.state.LoadMoreDeals) {
                self.store.state.MaxDealsShown += self.store.state.MaxDealsShown;
                self.store.state.LoadMoreDeals = false;
            }

            //Client-side pagination
            if (results.length > self.store.state.MaxDealsShown) {
                self.store.state.DealSearch.Results = results.slice(0, self.store.state.MaxDealsShown)
                self.store.state.DealSearch.MoreDealsLoading = false;
                self.store.state.DealSearch.HasMoreDeals = true;
            } else {
                self.store.state.DealSearch.Results = results;
                self.store.state.DealSearch.MoreDealsLoading = false;
                self.store.state.DealSearch.HasMoreDeals = false;
            }
        },
        performDealSearch: function () {
            var self = this;
            var request = this.store.getDealSearchRequest();
            var url = "/api/Search/HolidayDeals";
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    self.setSearchFinishedLoading();
                    self.getParkReviewInfo(response.Deals);
                },
                error: function (xhr, statusText, err) {
                    self.setSearchFinishedLoading();
                    self.store.state.DealSearch.MoreDealsLoading = false;
                    Common.ShowError("Unexpected error trying to load deals.");
                }
            });

        },
        getParkReviewInfo: function (deals)
        {
            var self = this;
            //Get Park Review information
            if (deals.length > 0) {
                var parkIDs = [];

                for (var i = 0; i < deals.length; i++) {
                    parkIDs.push(deals[i].ParkID);
                }

                var url = "/api/Park/GetParkListReviewInformation";
                var request = {
                    ParkIDs: parkIDs
                };

                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    data: JSON.stringify(request),
                    success: function (response) {
                        //Assign the rating information to each deal
                        for (var i = 0; i < deals.length; i++) {
                            var currentDeal = deals[i];
                            deals[i].Rating = _.filter(response.RatingList, function (val) {
                                return val.ParkID == currentDeal.ParkID;
                            });
                        }

                        self.store.state.AllDealResults = deals;
                        self.updateDealSearch(deals);
                    },
                    error: function (xhr, statusText, err) {
                        Common.ShowError("Unexpected error trying to populate park ratings on map.");
                    }
                });
            } else {
                self.updateDealSearch(deals);
            }
        },
        dynamicZIndex: function ()
        {
            if (window.DealSearchStore != undefined && window.DealSearchStore != null) {
                var inFront = false;

                var observer = new MutationObserver(function (mutations) {
                    mutations.forEach(function (mutationRecord) {
                        if (!inFront) {
                            $('.c-head__header-deals').css('z-index', '8');
                            inFront = true;
                        } else {
                            $('.c-head__header-deals').css('z-index', '6');
                            inFront = false;
                        }
                    });
                });

                var target = $('.c-filter__panel');

                if (target.length > 0) {
                    for (var i = 0; i < target.length; i++) {
                        observer.observe(target[i], { attributes: true, attributeFilter: ['style'] });
                    }
                }

            }
        },
        anchorToDealsHeading: function ()
        {
            var heading = document.getElementById('AllDealsHeading');
            this.$nextTick(function () {
                if (heading != null && heading != undefined)
                {
                    heading.scrollIntoView({ behavior: 'auto', block: 'start' });
                }
            });
        },
        bindFilterEvents: function () {
            var self = this;

            self.dynamicZIndex();

            window.DealSearchEventBus.$on('date-filter-update', function (data) {
                var valueChanged = self.store.state.StartDate._d != undefined ? (self.store.state.StartDate._d.toDateString() != data.start.toDateString()
                    || self.store.state.EndDate._d.toDateString() != data.end.toDateString()) : (self.store.state.StartDate.toDateString() != data.start.toDateString()
                        || self.store.state.EndDate.toDateString() != data.end.toDateString())

                self.store.state.StartDate = data.start;
                self.store.state.EndDate = data.end;

                if (valueChanged)
                {
                    self.store.state.DealSearch.Results = [];
                    self.anchorToDealsHeading();
                    self.$nextTick(function () {
                        self.performDealSearch();
                    });
                }
            });

            window.DealSearchEventBus.$on('guest-filter-update', function (data) {
                var valueChanged = (self.store.state.NumAdults != data.adults
                    || self.store.state.NumChildren != data.children
                    || self.store.state.NumInfants != data.infants)

                self.store.state.NumAdults = data.adults;
                self.store.state.NumChildren = data.children;
                self.store.state.NumInfants = data.infants;

                if (valueChanged)
                {
                    self.store.state.DealSearch.Results = [];
                    self.anchorToDealsHeading();
                    self.$nextTick(function () {
                        self.performDealSearch();
                    });
                }
            });

            window.DealSearchEventBus.$on('pets-filter-update', function (data) {
                var valueChanged = self.store.state.PetFriendly != data.isOn;

                self.store.state.PetFriendly = data.isOn;

                if (valueChanged)
                {
                    self.store.state.DealSearch.Results = [];
                    self.anchorToDealsHeading();
                    self.$nextTick(function () {
                        self.performDealSearch();
                    });
                }
            });

            window.DealSearchEventBus.$on('state-filter-update', function (data) {
                var valueChanged = self.store.state.States[0] != data[0];

                self.store.state.States = data;

                if (valueChanged)
                {
                    self.store.state.DealSearch.Results = [];
                    self.anchorToDealsHeading();
                    self.$nextTick(function () {
                        self.performDealSearch();
                    });
                }
            });

            window.DealSearchEventBus.$on('distance-filter-update', function (data) {
                var valueChanged = self.store.state.MaxDistanceRange != data.distance;

                self.store.state.MaxDistanceRange = data.distance;

                if (valueChanged) {
                    self.store.state.DealSearch.Results = [];
                    self.anchorToDealsHeading();
                    self.$nextTick(function () {
                        self.performDealSearch();
                    });
                }
            });

            window.DealSearchEventBus.$on('perks-filter-update', function (data) {
                var valueChanged = self.store.state.PerksDeals != data.isOn;

                self.store.state.PerksDeals = data.isOn;

                if (valueChanged) {
                    self.store.state.DealSearch.Results = [];
                    self.anchorToDealsHeading();
                    self.$nextTick(function () {
                        self.performDealSearch();
                    });
                }
            });
            

            window.SearchEventBus.$on(window.SearchEvents.LOAD_MORE_DEALS, function () {
                self.store.state.DealSearch.MoreDealsLoading = true;
                self.store.state.LoadMoreDeals = true;
                self.updateDealSearch(self.store.state.AllDealResults);
            });

            window.DealSearchEventBus.$on('deal-map-initialised', function () {
                self.populateDealMap();
            });
            
        }
    },
    computed: {
        deals: function () {
            return this.store.state.DealSearch.Results;
        },
        
    },
    mounted: function () {

        var self = this;

        this.bindFilterEvents();
        this.$nextTick(function () {
            this.performDealSearch();
        });
    },
    created: function () {
        var self = this;

        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (position) {
                //if this works, then we can use the distance filter
                self.store.state.CanUseDistance = true;
                self.store.state.Latitude = position.coods.latitude;
                self.store.state.Longitude = position.coods.longitude;
            });
        }
    }
});
;
Vue.component('deal-search-results-panel', {
    data: function () {
        return {
            store: window.DealSearchStore.state,
        }
    },
    computed: {
        deals: function () {
            return this.store.DealSearch.Results;
        },
        dealsLoading: function () {
            return this.store.DealSearch.MoreDealsLoading;
        },

        panelLoading: function () {
            return this.store.PanelLoading;
        },

        hasMoreDeals: function () {
            return this.store.DealSearch.HasMoreDeals;
        },

        totalDealsString: function () {
            return window.DealSearchStore.state.AllDealResults.length + ' Holiday Deals Returned';
        },

    },
    methods: {

        loadMoreDeals: function () {
            window.SearchEventBus.$emit(window.SearchEvents.LOAD_MORE_DEALS);
        },

    }
});
;
window.DealSearchStore = {
    state: {
        SearchTerm: "",
        StartDate: moment().endOf('day'),
        EndDate: moment().endOf('day').add(1,'day'),
        PetFriendly: false,
        PerksDeals: false,
        States: [],
        Latitude: 0,
        Longitude: 0,
        MaxDistanceRange: 100,
        NumAdults: 1,
        NumChildren: 0,
        NumInfants: 0,
        CanUseDistance: false,
        MaxDealsShown: 8,
        AllDealResults: [],
        DealCarouselResults: [],
        LoadMoreDeals: false,

        DEFAULT_ADULTS: 1,
        DEFAULT_CHILDREN: 0,
        DEFAULT_INFANTS: 0,
        DEFAULT_START_DATE: moment().endOf('day'),
        DEFAULT_END_DATE: moment().endOf('day').add(1, 'day'),

       
        DealSearch: {
            PageNumber: 1,
            ResultsPerPage: 1000,
            Results: [],
            MapResults: [],
            MoreDealsLoading: false,
            HasMoreDeals: false,
        },
        
        PanelLoading: true,

    },
   
    getDealSearchRequest: function () {

        return {
            SearchTerm: this.state.SearchTerm,
            StartDate: this.state.StartDate,
            EndDate: this.state.EndDate,
            PetFriendly: this.state.PetFriendly,
            PerksDeals: this.state.PerksDeals,
            States: this.state.States,
            Latitude: this.state.Latitude,
            Longitude: this.state.Longitude,
            MaxDistanceRange: this.state.MaxDistanceRange,
            HolidayType: this.state.HolidayType,
            ParkType: this.state.ParkType,
            NumAdults: this.state.NumAdults,
            NumChildren: this.state.NumChildren,
            NumInfants: this.state.NumInfants,
            PageNumber: this.state.DealSearch.PageNumber,
            ResultsPerPage: this.state.DealSearch.ResultsPerPage,
        }
    },
};;
Vue.use(AsyncComputed);

Vue.component('deals-near-carousel-data-wrapper', {
    props: ["max-deals"],
    data: function () {
        return {
            results: [],
            request: [],
            Ipaddress: '',
            store: window.DealSearchStore,
        }
    },
    computed:
    {
        items: function () {
            var topResults = this.$data.results
            this.store.state.DealCarouselResults = topResults;

            //trigger for most booked deals carousel
            if (this.$data.results.length > 0) {
                window.DealSearchEventBus.$emit('deal-results-found');
            }

            //Order by ascending distance and 1 deal per park only, Slice to maximum results size for carousel.
            topResults.sort(function (a, b) {
                return a.Distance - b.Distance;
            });

            topResults = _.uniqBy(topResults, "ParkID");

            topResults = topResults.slice(0, this.maxDeals);
            return topResults;
        },
        isDealsPage: function ()
        {
            return window.location.href.includes("holiday-deals");
        }
    },
    methods: {
        GetDealsNearMe: function () {

            var self = this;
            var request = this.store.getDealSearchRequest();
            var url = "/api/Search/HolidayDeals";
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    if (!self.isDealsPage) {
                        self.$data.results = response.Deals;
                    } else
                    {
                        self.getParkReviewInfo(response.Deals);
                    }
                },
                error: function (xhr, statusText, err) {
                    self.setSearchFinishedLoading();
                    self.store.state.DealSearch.MoreDealsLoading = false;
                    Common.ShowError("Unexpected error trying to load deals.");
                }
            });

        },
        getParkReviewInfo: function (deals) {
            var self = this;
            //Get Park Review information
            if (deals.length > 0) {
                var parkIDs = [];

                for (var i = 0; i < deals.length; i++) {
                    parkIDs.push(deals[i].ParkID);
                }

                var url = "/api/Park/GetParkListReviewInformation";
                var request = {
                    ParkIDs: parkIDs
                };

                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    data: JSON.stringify(request),
                    success: function (response) {
                        //Assign the rating information to each deal
                        for (var i = 0; i < deals.length; i++) {
                            var currentDeal = deals[i];
                            deals[i].Rating = _.filter(response.RatingList, function (val) {
                                return val.ParkID == currentDeal.ParkID;
                            });
                        }

                        self.store.state.DealCarouselResults = deals;
                        self.$data.results = deals;
                    },
                    error: function (xhr, statusText, err) {
                        Common.ShowError("Unexpected error trying to populate park ratings on map.");
                    }
                });
            } else {
                self.updateDealSearch(deals);
            }
        },
    },
    mounted: function () {
        this.GetDealsNearMe();
    }
});;
Vue.use(AsyncComputed);

Vue.component('latest-deals-carousel-data-wrapper', {
    props: ["max-deals"],
    data: function () {
        return {
            results: [],
            request: [],
            Ipaddress: '',
            deals: [],
            store: window.DealSearchStore,
        }
    },
    computed:
    {
        items: function () {
            return this.$data.deals;
        }
    },
    methods: {
        GetLatestDealsRightNow: function () {

            var self = this;
            var url = "/api/Deals/GetLatestDeals";
            $.ajax({
                type: 'GET',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                success: function (response) {
                    self.results = response.LatestDealsResult;
                },
                error: function (xhr, statusText, err) {
                    Common.ShowError("Unexpected error trying to load latest deals carousel.");
                }
            });

        },
        ProcessLatestDealsResponse: function (data) {
            this.$data.deals = [];
            for (var i = 0; i < data.length; i++) {
                var matchingResult = _.filter(this.store.state.DealCarouselResults, function (val) {
                    return val.Big4ID == data[i].OfferID;
                });;

                if (matchingResult.length != 0)
                {
                    this.$data.deals = this.$data.deals.concat(matchingResult);
                }
            }

            if (this.$data.deals.length == 0)
            {
                this.$data.deals = [];
            }
        },
    },
    mounted: function () {
        var self = this;

        this.GetLatestDealsRightNow();
        window.DealSearchEventBus.$on('deal-results-found', function () {
            self.ProcessLatestDealsResponse(self.$data.results);
        });
    }
});;
Vue.use(AsyncComputed);

Vue.component('perks-plus-deals-carousel-data-wrapper', {
    props: ["max-deals"],
    data: function () {
        return {
            results: [],
            request: [],
            Ipaddress: '',
            deals: [],
            store: window.DealSearchStore,
        }
    },
    computed:
    {
        items: function () {
            return this.$data.deals;
        }
    },
    methods: {
        GetPerksPlusDealsRightNow: function () {

            var self = this;
            var url = "/api/Deals/GetPerksPlusExclusiveDeals";
            $.ajax({
                type: 'GET',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                success: function (response) {
                    self.results = response.LatestDealsResult;
                },
                error: function (xhr, statusText, err) {
                    Common.ShowError("Unexpected error trying to load perks plus deals carousel.");
                }
            });

        },
        ProcessPerksPlusDealsResponse: function (data) {
            this.$data.deals = [];
            for (var i = 0; i < data.length; i++) {
                var matchingResult = _.filter(this.store.state.DealCarouselResults, function (val) {
                    return val.Big4ID == data[i].OfferID;
                });;

                if (matchingResult.length != 0) {
                    this.$data.deals = this.$data.deals.concat(matchingResult);
                }
            }

            if (this.$data.deals.length == 0) {
                this.$data.deals = [];
            }
        },
    },
    mounted: function () {
        var self = this;

        this.GetPerksPlusDealsRightNow();
        window.DealSearchEventBus.$on('deal-results-found', function () {
            self.ProcessPerksPlusDealsResponse(self.$data.results);
        });
    }
});;
Vue.use(AsyncComputed);

Vue.component('popular-deals-carousel-data-wrapper', {
    props: ["max-deals"],
    data: function () {
        return {
            results: [],
            request: [],
            Ipaddress: '',
            deals: [],
            store: window.DealSearchStore,
        }
    },
    computed:
    {
        items: function () {
            return this.$data.deals;
        }
    },
    methods: {
        GetPopularDealsRightNow: function () {

            var self = this;
            var url = "/api/Deals/GetRecentMostBookedDeals";
            $.ajax({
                type: 'GET',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                success: function (response) {
                    self.results = response.RecentMostBookedDealsResult;
                },
                error: function (xhr, statusText, err) {
                    Common.ShowError("Unexpected error trying to load popular deals carousel.");
                }
            });

        },
        ProcessPopularDealsResponse: function (data) {
            this.$data.deals = [];
            for (var i = 0; i < data.length; i++) {
                var matchingResult = _.filter(this.store.state.DealCarouselResults, function (val) {
                    return val.Big4ID == data[i].OfferID;
                });;

                if (matchingResult.length != 0)
                {
                    this.$data.deals = this.$data.deals.concat(matchingResult);
                }
            }

            if (this.$data.deals.length == 0)
            {
                this.$data.deals = [];
            }
        },
    },
    mounted: function () {
        var self = this;

        this.GetPopularDealsRightNow();
        window.DealSearchEventBus.$on('deal-results-found', function () {
            self.ProcessPopularDealsResponse(self.$data.results);
        });
    }
});;
Vue.component('gift-card-price-table', {
    template: "#GiftCardPriceTableTemplate",
    data: function () {
        return {
            isLoading: false,
        }
    },
    computed: {
        canAddToCart: function () {
            return true;
        }
    },
    methods: {
        addToCart: function () {
            var giftcards = [];

            $.each(this.$refs.presetAmounts, function (i, e) {

                if (e.quantity > 0) {
                    giftcards.push({
                        Denomination: e.$attrs.amount,
                        Quantity: e.quantity,
                    });
                }

            });

            for (var i = 0; i < this.$refs.customAmounts.$refs.amount.length; i++) {


                if (this.$refs.customAmounts.$refs.amount[i].quantity > 0) {
                    giftcards.push({
                        Denomination: this.$refs.customAmounts.$refs.inputs[i].value,
                        Quantity: this.$refs.customAmounts.$refs.amount[i].quantity,
                    });
                }
            }

        }
    },
});;
Vue.component('gift-card-price-table-wrapper', {
    mixins:[MIXIN_CART],
    data: function () {
        return {
            isLoading: false,
        }
    },
    computed: {
        canAddToCart: function () {
            return this.cartLoaded;
        },
        active: function () {
            return this.$parent.active;
        },
        props: function () {
            return {
                toggle: this.toggle,
                active: this.active,
                canAddToCart: this.canAddToCart,
                isLoading: this.isLoading,
                addToCart: this.addToCart,
            }
        }
    },
    methods: {
        addToCart: function () {

            var self = this;
            self.isLoading = true;
            var giftcards = [];

            $.each(this.$refs.presetAmounts, function (i, e) {

                if (e.quantity > 0) {
                    giftcards.push({
                        Denomination: e.$attrs.amount,
                        Quantity: e.quantity,
                    });
                }

            });

            if (this.$refs.customAmounts.$refs.amount) {
                for (var i = 0; i < this.$refs.customAmounts.$refs.amount.length; i++) {

                    var value = parseInt(this.$refs.customAmounts.$refs.inputs[i].value);
                    if (isNaN(value)) {
                        continue;
                    }

                    if (value < 50) {
                        Common.ShowError("Minimum gift card value is $50");
                        self.isLoading = false;
                        return;
                    }

                    if (this.$refs.customAmounts.$refs.amount[i].quantity > 0) {
                        giftcards.push({
                            Denomination: this.$refs.customAmounts.$refs.inputs[i].value,
                            Quantity: this.$refs.customAmounts.$refs.amount[i].quantity,
                        });
                    }
                }
            }

            if (giftcards.length == 0) {
                self.isLoading = false;
                return;
            }

            window.CartEventBus.$emit(window.CartEvents.ADD_GIFTCARDS, giftcards,
                function () {
                    self.isLoading = false;
                },
                function () {
                    self.isLoading = false;
                    Common.ShowError("Error trying to add gift card to cart.")
                });

        },
        toggle: function () {
            return this.$parent.toggle();
        }
    },
});;
Vue.component('article-card', {

    mixins: [MIXIN_SEARCH_SAVED_SEARCHES],
    props: ["article"],
    template: "#ARTICLE_CARD_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {}
    },
    computed: {
        isMobile: function () {
            return false;
        },
        showImageCarousel: function () {
            if (this.isMobile) {
                return false;
            }
            else {
                if (this.article.Image.length > 1) {
                    return true;
                }
            }

            return false;
        },
    },
    methods: {
        GoToUrl: function () {
            this.UpdateCookie({
                url: this.article.ArticleUrl,
                title: this.article.ArticleName,
                icon: 'bulb'
            });

            window.location.href = this.article.ArticleUrl;
        }
    },
    mounted: function () {
    }

});
;
Vue.component('article-card-load-button', {

    
    props:["page-number","sub-category", "article-cards"],
    template: "#ARTICLE_CARD_LOAD_BUTTON_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {}
    },
    computed: {
 
    },
    methods: {
        loadMoreArticles: function ()
        {
            var self = this;

            $.ajax({
                type: 'GET',
                url: '/api/Article/GetArticleCards' + '?pageNumber='+ self.pageNumber +'&subCategory='+ self.subCategory,
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    self.pageNumber = data.pageNumber;
                    if (self.articleCards == undefined) {
                        self.articleCards = data.ArticleCards;
                    }
                    else {
                        //for (let card of data.ArticleCards)
                        //{
                        //    self.articleCards.push(card);
                        //}

                        var _iteratorNormalCompletion = true;
                        var _didIteratorError = false;
                        var _iteratorError = undefined;

                        try {
                            for (var _iterator = data.ArticleCards[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
                                var card = _step.value;
                                self.articleCards.push(card);
                            }
                        } catch (err) {
                            _didIteratorError = true;
                            _iteratorError = err;
                        } finally {
                            try {
                                if (!_iteratorNormalCompletion && _iterator.return != null) {
                                    _iterator.return();
                                }
                            } finally {
                                if (_didIteratorError) {
                                    throw _iteratorError;
                                }
                            }
                        }

                    }
                },
                error: function (xhr, ajaxOptions, thrownError) {

                }
            });
        }
    },
    mounted: function () {
    },
    created: function ()
    {

    }

});
;
Vue.use(AsyncComputed);

Vue.component('deal-group-filter-data-wrapper', {
    data: function () {
        return {
            items: [],
            results:[],
            request: [],
            Ipaddress: '',
            limitNumber:"8",
            totalCount:""
        }
    },
    methods: {
        GetAllHolidayDeals: function ()
        {
            var results = [];
            request = {
                SearchTerm: "VIC"
            }
            var count = "";
            var self = this;
            var url = "api/Search/SiteSearch";
            $.ajax({
                type: 'GET',
                //headers: {
                //    'Authorization': 'Bearer ' + CookieHelper.GetCookieValue('access_token'),
                //},
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: request,
                success: function (response) {
                    response = JSON.parse(response);
                    self.items = response.Deals;
                    var count = self.items;
                    self.totalCount = count.length;
                },
                error: function (xhr, statusText, err) {
                }
            });
        },
        LoadMoreDeals: function () {
            this.limitNumber = this.totalCount;
          
        }
    },
    mounted: function () {
            this.GetAllHolidayDeals();
      
            this.items = [{ "title": "BIG4 Resort", "tag": "Premier", "price": "From $30 per night", "images": [{ "lg": "https://placehold.it/340x430", "md": "https://placehold.it/250x317" }] },
                                 { "title": "Beacon Resort", "tag": "Premier", "price": "From $30 per night", "images": [{ "lg": "https://placehold.it/340x430", "md": "https://placehold.it/250x317" }] },
                                 { "title": "BIG4 Beacon Resort1", "tag": "Premier", "price": "From $30 per night", "images": [{ "lg": "https://placehold.it/340x430", "md": "https://placehold.it/250x317" }] },
                                 { "title": "BIG4 Beacon Resort2", "tag": "Premier", "price": "From $30 per night", "images": [{ "lg": "https://placehold.it/340x430", "md": "https://placehold.it/250x317" }] },
                                 { "title": "BIG4 Beacon Resort", "tag": "Premier", "price": "From $30 per night", "images": [{ "lg": "https://placehold.it/340x430", "md": "https://placehold.it/250x317" }] },
                                 { "title": "BIG4 Beacon", "tag": "Premier", "price": "From $30 per night", "images": [{ "lg": "https://placehold.it/340x430", "md": "https://placehold.it/250x317" }] },
                                 { "title": "BIG4 Resort", "tag": "Premier", "price": "From $30 per night", "images": [{ "lg": "https://placehold.it/340x430", "md": "https://placehold.it/250x317" }] },
                                 { "title": "BIG4 Beacon Resort", "tag": "Premier", "price": "From $30 per night", "images": [{ "lg": "https://placehold.it/340x430", "md": "https://placehold.it/250x317" }] }, ]
        }
});;
Vue.use(AsyncComputed);
Vue.component('deals-carousel-data-wrapper', {
    props: ['ParkId', 'WidgetPlaceHolderUrl'],
    data: function () {
        return {
            items: [],
            results: [],
            request: [],
            observer: null,
        }
    },
    methods: {

        GetDeals: function () {
            var results = [];

            var count = "";
            var self = this;
            var url = self.WidgetPlaceHolderUrl + "/GetFeaturedDeals";
            var request = {
                SearchTerm: ""
            };
            $.ajax({
                type: 'GET',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: request,
                success: function (response) {
                    response = response;
                    self.items = response.Deals;
                },
                error: function (xhr, statusText, err) {
                }
            });

        },
        GetParkDeals: function () {
            var self = this;
            var url = "";

            if (self.WidgetPlaceHolderUrl != "") {
                url = self.WidgetPlaceHolderUrl + "/GetDealsForPark";
            }
            var count = "";
            $.ajax({
                type: 'GET',
                url: url,
                contentType: 'application/json; charset=utf-8',
                data: { 'parkID': JSON.stringify(self.ParkId) },
                success: function (response) {
                    response = JSON.parse(response);
                    self.items = response.Deals;
                },
                error: function (xhr, statusText, err) {
                }
            });

        },
        createObserver: function () {
            var options = {
                root: null,
                threshold: "0",
            };
            this.observer = new IntersectionObserver(this.handleIntersect, options);
            this.observer.observe(this.$el);
        },
        handleIntersect: function (entries, observer) {
            var self = this;
            entries.forEach(function (entry) {
                if (entry.isIntersecting) {
                    self.GetDeals();
                    self.observer.unobserve(self.$el);
                }
            });
        },
    },
    mounted: function () {
        if (this.WidgetPlaceHolderUrl != "") {
            this.GetParkDeals();
        }
        else {
            //this.GetDeals();

            if (window["IntersectionObserver"]) {
                this.createObserver();
            } else {
                this.GetDeals();
            }

        }


    }
});;
Vue.use(AsyncComputed);

Vue.component('related-parks-deal-data-wrapper', {
    props: ['DealId', 'DealDetails', 'DealName'],
    data: function () {
        return {

            items: [],

        }
    },
    methods: {
        GetAllRelatedParkDeals: function () {

            var self = this;

            //var dealDetailsList = JSON.parse(self.DealDetails);
            //var cabinIDsList = dealDetailsList.AccommodationList;
            //var siteIDsList = dealDetailsList.SiteList;
            //var accomIDList = $.merge($.merge([], cabinIDsList), siteIDsList);

            var documentids = JSON.parse(self.DealDetails);

            //var url = "/api/Search/KentcioDealAccommodationSearch";
            var url = '/api/Search/GetKenticoDealAccommodationSearchByDocumentIDs';
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                //data: JSON.stringify(accomIDList),
                data: JSON.stringify(documentids),
                success: function (response) {

                    var accommodationitems = [];
                    if (!jQuery.isEmptyObject(response)) {
                        $.each(response, function (key, value) {
                            var itemObject = { "AccommodationType": value.AccommodationType, "Guests": value.Guest, "Beds": value.Bed, "Bath": value.Bath, "ImageUrl": value.ImageUrl, "Url": value.Url }
                            accommodationitems.push(itemObject);
                        });
                        self.items = accommodationitems;
                        window.DealStore.UpdateDealName(self.DealName);
                    }

                },
                error: function (xhr, statusText, err) {
                }
            });
        },

    },
    mounted: function () {
        //this.GetAllRelatedParkDeals();
    }
});;
Vue.component('home-hero-banner', {
    data: function() {
        return {
            show: false,
        }
    },
    computed: {
        scrolled: function () {
            return this.show;
        }
    },
    methods: {
    },
    mounted: function ()
    {
        var self = this;
        var element = document.getElementsByClassName('c-banner__shape')[0];

        var observer = new IntersectionObserver(function (entries)
        {
            if (entries[0].isIntersecting == false) {
                self.show = true;
            } else {
                self.show = false;
            }
        });

        observer.observe(element)
    }
});;
Vue.component('home-hero-banner-image-wrapper', {
  props: {
    imageUrl: "",
  },
  computed: {
    heroImageUrl: function() {
      if(this.$mq !== 'sm' && this.$mq !== 'md') {
        return this.$attrs.imageurl
      } else {
        return "";
      }
    }
  },
});;
Vue.component("park-map-view-widget", {
    template: "#PARK_MAP_VIEW_TEMPLATE",
    props: ["parks"],
    data: function () {
        return {
            mapId: _.uniqueId('map_'),
        }
    },
    methods:
    {
        init: function () {
            new AzureMapWithClusteredParkMarkers(this.mapId, this.parks)
        },
    },
    mounted: function () {
        this.init();
    }
});;
Vue.use(AsyncComputed);

Vue.component('highest-rated-parks-carousel-data-wrapper', {
    data: function () {
        return {
            items: [],
            results: [],
            request: [],
            Ipaddress: '',
            observer: null,
        }
    },
    methods: {

        GetHighestRatedParks: function () {
            
            var self = this;
            var url = "/api/homepage/GetHighestRatedParksDetails";
            $.ajax({
                type: 'GET',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                success: function (response) {
                    var data = jQuery.parseJSON(response);

                    self.items = data;

                },
                error: function (xhr, statusText, err) {
                }
            });

        },
        createObserver: function () {
            var options = {
                root: null,
                threshold: "0",
            };
            this.observer = new IntersectionObserver(this.handleIntersect, options);
            this.observer.observe(this.$el);
        },
        handleIntersect: function (entries, observer) {
            var self = this;
            entries.forEach(function (entry) {
                if (entry.isIntersecting) {
                    self.GetHighestRatedParks();
                    self.observer.unobserve(self.$el);
                }
            });
        },
    },
    mounted: function () {
        if (window["IntersectionObserver"]) {
            this.createObserver();
        } else {
            this.GetHighestRatedParks();
        }

        

    }
});;
//Vue.use(AsyncComputed);
//Vue.component('parks-near-carousel-data-wrapper', {});


Vue.component('parks-near-carousel-data-wrapper', {
    data: function () {
        return {
            items: [],
            results:[],
            request: [],
            bresponse: [],
            parks: [],
            deals: [],
            regions: [],
            articles: [],
            Ipaddress:''
        }
    },
    methods: {
        GetIPAddress : function()
        {
            var self = this;
            var StateCode = "";
            axios.get('api/homepage/GetIPAddress').then(function (response) {
                StateCode = response.data;
                self.GetParksNearMe(StateCode);
            }).catch(function (error) {
                this.error = error;
            });
        },
        GetParksNearMe: function (StateCode)
        {
            var request = {};
            var startDate = moment().format(); // Today's date (ISO format)
            var tomorrowDate = moment().add(1, 'day').format();

            request = {
                SearchTerm:"park",
                StartDate: startDate,
                EndDate: tomorrowDate,
                PetFriendly:"",
                States: StateCode,
                Latitude:"",
                Longitude:"",
                MaxDistanceRange:"",
                PageNumber:"",
                ResultsPerPage:""
            }
            var self = this;
            var url = "/api/Search/ParkSearch";
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    response = JSON.parse(response);
                    self.items = response.Parks;
                   
                },
                error: function (xhr, statusText, err) {
                }
            });
        
        },
        formatPrice:function(value) {
            var val = value.toFixed(2);
            return val;
        }
     
    },
    mounted: function () {
            this.GetIPAddress();
   
        }
});;
Vue.use(AsyncComputed);

Vue.component('parks-near-carousel-data-wrapper', {
    data: function () {
        return {
            items: [],
            results: [],
            request: [],
            Ipaddress: ''
        }
    },
    methods: {

        GetParksNearMe: function () {
            var self = this;
            var latitude = null;
            var longitude = null;

            //Checking permissions this way does not work on Edge and Safari, so use normal method if using that browser
            if (!(window.navigator.userAgent.indexOf("Edge") > 0) && !(window.navigator.userAgent.indexOf("Safari") > 0) && navigator.permissions) {
                navigator.permissions.query({ name: 'geolocation' })
                    .then(function (result) {
                        console.log(result);
                        if (result.state === "granted") {
                            navigator.geolocation.getCurrentPosition(function (position) {
                                latitude = position.coords.latitude;
                                longitude = position.coords.longitude;

                                // console.log("Get parks near me : ", request);
                                var url = "api/homepage/GetParksNearMeDetails?latitude=" + latitude + "&longitude=" + longitude;
                                $.ajax({
                                    type: 'GET',
                                    url: url,
                                    contentType: 'application/json; charset=utf-8',
                                    dataType: 'json',
                                    success: function (response) {
                                        var data = jQuery.parseJSON(response);

                                        self.items = data;
                                    },
                                    error: function (xhr, statusText, err) {
                                        // console.log(xhr);
                                    }
                                });
                            })
                        } else {
                            // console.log("Get parks near me : ", request);
                            var url = "api/homepage/GetParksNearMeDetails?latitude=" + latitude + "&longitude=" + longitude;
                            $.ajax({
                                type: 'GET',
                                url: url,
                                contentType: 'application/json; charset=utf-8',
                                dataType: 'json',
                                success: function (response) {
                                    var data = jQuery.parseJSON(response);

                                    self.items = data;
                                },
                                error: function (xhr, statusText, err) {
                                    // console.log(xhr);
                                }
                            });
                        }

                    });
            } else {
                var self = this;
                var url = "api/homepage/GetParksNearMeDetails?latitude=" + latitude + "&longitude=" + longitude;
                $.ajax({
                    type: 'GET',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    success: function (response) {
                        var data = jQuery.parseJSON(response);

                        self.items = data;
                    },
                    error: function (xhr, statusText, err) {
                        // console.log(xhr);
                    }
                });
            }



        }
    },
    mounted: function () {
        this.GetParksNearMe();

    }
});;
Vue.use(AsyncComputed);

Vue.component('recently-booked-parks-carousel-data-wrapper', {
    props:["cards"],
    data: function () {
        return {
            items: [],
            observer: null,
        }
    },
    methods: {
        createObserver: function () {
            var options = {
                root: null,
                threshold: "0",
            };
            this.observer = new IntersectionObserver(this.handleIntersect, options);
            this.observer.observe(this.$el);
        },
        handleIntersect: function (entries, observer) {
            var self = this;
            entries.forEach(function (entry) {
                if (entry.isIntersecting) {
                    self.items = self.cards;
                    self.observer.unobserve(self.$el);
                }
            });
        },
       
    },
    mounted: function () {
        var self = this;
        if (window["IntersectionObserver"]) {
            this.createObserver();
        } else {
            self.items = self.cards;
        }

       
    }
});;
Vue.component('review-data-wrapper', {
    props:["cards"],
    data: function () {
        return {
            items: [],
           
        }
    },
    methods: {
       
    },
    mounted: function () {
       
            this.items = this.cards;
       
    }
});;
Vue.component('review-card', {

    /*
     * Initial state of the component's data.
     */
    props:['review'],
    data: function () {
        return {
            reviewDetails:[],
        }
    },

    computed: {
        formatReviewDate: function () {
            return moment(this.review.ReviewDate).format("DD MMM, YYYY");
        },
        getRating: function () {
            var ratingString = this.review.Rating.toFixed(1).toString();
            var ratingStringSet = ratingString.split(".");

            if (ratingStringSet[1] == "0") {
                return ratingStringSet[0];
            }
            else {
                return ratingString;
            }
        },
        getRatingPercent: function () {

            var rating = this.review.Rating * 100 / 10;
            return rating;
        },
        getReviewSourceImage: function () {
            var url = "";

            switch (this.review.ReviewSource.toLowerCase()) {
                case "google":
                    url = "/Content/ReviewIcons/google_logo.png";
                    break;

                case ("ctrip (zh)"):
                    url = "/Content/ReviewIcons/ctrip_logo.png";
                    break;

                case ("booking"):
                    url = "/Content/ReviewIcons/booking_logo.png";
                    break;

                case ("wotif"):
                    url = "/Content/ReviewIcons/wotif_logo.png";
                    break;

                case ("expedia"):
                    url = "/Content/ReviewIcons/expedia_logo.png";
                    break;

                case ("agoda"):
                    url = "/Content/ReviewIcons/agoda_logo.png";
                    break;

                case ("facebook"):
                    url = "/Content/ReviewIcons/facebook_logo.png";
                    break;

                case ("turu"):
                    url = "/Content/ReviewIcons/turu_logo.png";
                    break;

                case ("hotels.com"):
                    url = "/Content/ReviewIcons/hotels_logo.jpg";
                    break;
            }
            if (url != "" || url != null) {
                return Common.CdnAssetUrl(url);
            }
            else {
                return "https://via.placeholder.com/60x60/333333";
            }
        },
    },
    mounted: function () {
       
    },

});
;
Vue.component('reviews-load-button', {

    
    props:["reviews-number",],
    template: "#ReviewsLoadButtonTemplate",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {}
    },
    computed: {
 
    },
    methods: {
        loadMoreReviews: function ()
        {

            this.$parent.$emit("LOAD-MORE-REVIEWS");
            //var self = this;

            //$.ajax({
            //    type: 'GET',
            //    url: '/api/Article/GetReviews',
            //    contentType: 'application/json; charset=utf-8',
            //    success: function (data) {
            //        self.reviewsNumber = data.reviewsNumber;
            //        if (self.reviews == undefined) {
            //            self.reviews = data.reviews;
            //        }
            //        else {
            //            for (let review of data.reviews)
            //            {
            //                self.reviews.push(review);
            //            }
            //        }
            //    },
            //    error: function (xhr, ajaxOptions, thrownError) {

            //    }
            //});
        }
    },
    mounted: function () {
    },
    created: function ()
    {

    }

});
;
Vue.component('tip-inspiration-carousel-data-wrapper', {
    props:["cards"],
    data: function () {
        return {
            items: [],
            observer: null,
        }
    },
    methods: {
        createObserver: function () {
            var options = {
                root: null,
                threshold: "0",
            };
            this.observer = new IntersectionObserver(this.handleIntersect, options);
            this.observer.observe(this.$el);
        },
        handleIntersect: function (entries, observer) {
            var self = this;
            entries.forEach(function (entry) {
                if (entry.isIntersecting) {
                    self.items = self.cards;
                    self.observer.unobserve(self.$el);
                }
            });
        },

    },
    mounted: function () {
        var self = this;
        if (window["IntersectionObserver"]) {
            this.createObserver();
        } else {
            self.items = self.cards;
        }
    }
});;
Vue.component('footer-forgot-password-wrapper', {
    data: function () {
        return {
        };
    },
    methods: {
        showForgotPasswordModalFromFooter: function () {
            window.LoginStore.showForgotPasswordModal();
        },
    },
    mounted: function ()
    {
        var self = this;
        window.LoginEventBus.$on("forgotPasswordModalUnregistered", function () {
            window.LoginStore.registerForgotPasswordModal(self);
        });
    }
});;
Vue.component('footer-sign-in-wrapper', {
    data: function () {
        return {
        };
    },
    methods: {
        showSignInModalFromFooter: function () {
            window.LoginStore.showSignInModal();
        },
    },
});;
Vue.component('forgot-password', {
    template: "#FORGOT_PASSWORD_TEMPLATE",
    data: function () {
        return {
           
        };
    },
    methods: {
        show: function () {
            this.$refs.modalWrapper.openModal();
        }
    },
    mounted: function () {
        window.LoginStore.registerForgotPasswordModal(this);
    }
   
});;
Vue.component('forgot-password-wrapper', {
    data: function () {
        return {
                email: "",
                isLoading: false,
                resetLinkSent: false,
        };
    },
    methods: {
        callApi: function () {

            var self = this;
            self.isLoading = true;


            $.ajax({
                type: 'POST',
                url: '/api/Login/SendForgotPassword',
                contentType: 'application/json; charset=utf-8',
                data: JSON.stringify(self.email),
                success: function (response) {

                    self.isLoading = false;
                    if (response.Status == eResponseStatus.Ok) {
                        self.resetLinkSent = true;
                    }
                    else {
                        Common.ShowError("Unexpected error has occurred.")
                    }
                },
                error: function (xhr, statusText, err) {
                    self.isLoading = false;
                    Common.ShowError("Unexpected error has occurred.");
                }
            });
            
        },
        submit: function () {

            this.pristine = new Pristine(this.$el, {
                classTo: "c-field",
                errorClass: 'has-error',
                successClass: 'is-success',
                errorTextParent: 'c-input',
                errorTextClass: 'c-field__error'
            });

            var valid = this.pristine.validate();

            if (valid) {
                this.callApi();
            }
        }
    },
    mounted() {
        document.getElementById("forgotPasswordForm").addEventListener("submit", function (event) {
            event.preventDefault()
        });
    },
    
});;

Vue.component('login-handler', {

    template: "<div style='display:none'></div>",

    mounted: function () {

        window.LoginEventBus.$on(window.LoginEvents.SHOW_LOGIN_MODAL, function (payload, callback) {
            window.LoginStore.showSignInModal();
        });

        window.LoginEventBus.$on(window.LoginEvents.PERFORM_LOGIN, function (payload,callback) {

            //now that we have all the event handlers, we want to send off a request to see if there is an existing cart
            $.post({
                url: '/api/Login/Submit',
                data: payload,
                dataType: "json",
                success: function (response) {

                    if (response.Status == window.eResponseStatus.Ok) {
                        window.LoginEventBus.$emit(window.LoginEvents.HIDE_LOGIN_MODAL, function () {
                            window.LoginStore.updateMembership(response.Membership);
                            window.LoginEventBus.$emit(window.LoginEvents.AUTHENTICATED);

                            if (!!callback) {
                                callback();
                            }
                        });
                    }
                    else {
                        window.LoginEventBus.$emit(window.LoginEvents.AUTHENTICATION_FAILURE, response.ResponseMessage);
                    }

                },
                error:function(response) {
                    //failure
                    window.LoginEventBus.$emit(window.LoginEvents.AUTHENTICATION_FAILURE,"Unexpected error has occurred.")
                    
                }
            });

        });

        window.LoginEventBus.$on(window.LoginEvents.REGISTER_USER, function (payload,callback) {


            //now that we have all the event handlers, we want to send off a request to see if there is an existing cart
            $.post({
                url: '/api/Login/Register',
                data: payload,
                dataType: "json",
                success: function (response) {

                    if (response.Status == window.eResponseStatus.Ok) {
                        window.LoginEventBus.$emit(window.LoginEvents.HIDE_LOGIN_MODAL, function () {
                            window.LoginStore.updateMembership(response.Membership);
                            window.LoginEventBus.$emit(window.LoginEvents.REGISTERED);

                            if (callback) {
                                callback(response);
                            }
                        });
                    }
                    else {
                        window.LoginEventBus.$emit(window.LoginEvents.AUTHENTICATION_FAILURE, response.ResponseMessage);
                        if (callback) {
                            callback(response);
                        }
                    }

                },
                error: function (response) {
                    //failure
                    window.LoginEventBus.$emit(window.LoginEvents.AUTHENTICATION_FAILURE, "Unexpected error has occurred.")
                }
            });

        });
        
        window.LoginEventBus.$on(window.LoginEvents.SHOW_FORGOT_PASSWORD_MODAL, function (payload, callback) {
            window.LoginStore.showForgotPasswordModal();
        });
    }
});
;
Vue.component('login-status-wrapper', {
    data: function () {
        return {
            state: {
                loginStore: window.LoginStore.state
            }
        };
    },
    computed: {
        isLoggedIn: function () {
            if (this.state.loginStore.membership) {
                if (this.state.loginStore.membership.MemberID) {
                    return true;
                }
            }

            return false;
        }
    },
    
});;
window.LoginStore = {
    state: {
        membership: {},
        details: {
            FirstName: "",
            LastName: "",
            Address: "",
            UnitNumber: "",
            StreetNumber: "",
            StreetName: "",
            City: "",
            Suburb: "",
            State: "",
            Postcode: "",
            EmailAddress: "",
            MobileNumber: "",
            CompanyName: "",

        },
        modal: null,
    },
    signInModal: null,
    forgotPasswordModal: null,
    updateMembership: function (membership) {
        this.state.membership = membership;
    },
    registerSignInModal: function (modal) {
        //if not null assign
        if (this.signInModal == null) {
            this.signInModal = modal;
        }
    },
    showSignInModal: function () {
        if (this.signInModal && this.signInModal.$refs.modalWrapper) {
            this.signInModal.$refs.modalWrapper.openModal();
        } else
        {
            //TW: Emit to the sign in component that we need it to register itself.
            //Specifically for tablets when rotated to ensure footer links to sign in modal operate.
            this.registerSignInModal(this.state.modal);
            window['LoginEventBus'].$emit('signInModalUnregistered');
        }
    },
    registerForgotPasswordModal: function (modal) {
            this.forgotPasswordModal = modal;
    },
    showForgotPasswordModal: function () {
        if (this.forgotPasswordModal && this.forgotPasswordModal.$refs.modalWrapper) {
            this.forgotPasswordModal.$refs.modalWrapper.openModal();
        } else
        {
            this.registerForgotPasswordModal(this.state.modal);
            window['LoginEventBus'].$emit('forgotPasswordModalUnregistered');
        }
    }


};;
Vue.component('logout-wrapper', {
    data: function () {
        return {

        }
    },

    methods: {
        Logout: function () {
            $.post({
                url: '/api/Login/Logout',
                success: function (response) {
                    window.location.href = "/";
                },
                error: function (response) {
                    Common.ShowError("Unexpected error trying to logout.");
                }
            });
        }
    },
});;
Vue.component('register-perks', {
    template:'#RegisterTemplate',
    data: function () {
        return {
           
        };
    },
    methods: {
        show: function () {
            this.$refs.modalWrapper.openModal();
        }
    },
    computed: {
    },
    mounted: function () {
        var self = this;
        //window.LoginEventBus.$on(window.LoginEvents.HIDE_LOGIN_MODAL, function (callback) {

        //    self.$refs.modalWrapper.showModal = false;
        //    $('body').removeClass('no-scroll');

        //    //we need to do this to give the modal tranisition time to slide out
        //    //before we update
        //    setTimeout(function () {
        //        if (callback != null) {
        //            callback();
        //        }

        //    }, 300);

            
        //});
    }
   
});;
Vue.component('register-wrapper', {
    mixins: [MIXIN_PASSWORD_CHECKER, MIXIN_MEMBERSHIP],
    data: function () {
        return {
            email: "",
            password: "",
            firstName: "",
            lastName: "",
            state:"",
            newsletterSignup: true,
            confirmPassword: "",
            isLoading: false,
            passwordsDontMatch: false,
            hasError: false,
            passwordInvalid: false,
            checkingEmail: false,
            isMember: false,
            signedUp:false,
        };
    },
    watch: {
        password: function () {
            this.passwordsDontMatch = false;
            this.hasError = false;
            this.passwordInvalid = false;
        },
        confirmPassword: function () {
            this.passwordsDontMatch = false;
            this.hasError = false;
            this.passwordInvalid = false;
        },

        email: _.debounce(function (value) {
            this.isMember = false;

            var self = this;

            var email = document.querySelector('#email');
            var pristine = new Pristine(this.$el)
            var valid = pristine.validate(email);

            if (valid) {
                this.checkEmailAddress(function (response) {
                    window.LoginEventBus.$emit(window.LoginEvents.SHOW_LOGIN_MODAL);
                });
            }
        },500),
    },
    methods: {
        checkEmailAddress: function (callback) {

            var self = this;

            this.checkingEmail = true;
            $.get({
                url: '/api/Checkout/MembershipLookup',
                data: { 'email': this.email },
                dataType: 'json',
                success: function (response) {

                    self.checkingEmail = false;
                    if (response) {
                        self.isMember = true;
                        callback(response);
                    }
                },
                error: function () {
                    self.checkingEmail = false;
                }
            });
        },
        registerApi: function () {
            var self = this;
            if (self.isMember) {
                Common.ShowError("There is already a membership associated with this email address.");
                return;
            }

            var self = this;
            var req = {
                EmailAddress: self.email,
                Password: self.password,
                FirstName: self.firstName,
                LastName: self.lastName,
                State: self.state,
                NewsletterSignup:self.newsletterSignup,
            };

            self.isLoading = true;
            $.ajax({
                type: 'POST',
                url: '/api/Login/Register',
                contentType: 'application/json; charset=utf-8',
                dataType: "json",
                data: JSON.stringify(req),
                success: function (response) {

                    if (response.Status == eResponseStatus.Ok) {
                        self.isLoading = false;
                        self.signedUp = true;
                        window.LoginStore.updateMembership(response.Membership);
                        window.LoginEventBus.$emit(window.LoginEvents.AUTHENTICATED);
                    }
                    else {
                        self.isLoading = false;
                        Common.ShowError("Unexpected error has occurred.")
                    }
                },
                error: function (xhr, statusText, err) {
                    self.isLoading = false;
                    Common.ShowError("Unexpected error has occurred.");
                }
            });
        },
        register: function () {

            if (this.password != this.confirmPassword) {
                this.passwordsDontMatch = true;
                this.hasError = true;
                return;
            }

            if (!this.passwordMeetsRequirements(this.password)) {
                this.passwordInvalid = true;
                this.hasError = true;
                return;
            }

            this.pristine = new Pristine(this.$el, {
                classTo: "c-field",
                errorClass: 'has-error',
                successClass: 'is-success',
                errorTextParent: 'c-input',
                errorTextClass: 'c-field__error'
            });

            var valid = this.pristine.validate();

            if (valid) {
                this.registerApi();
            }
        }
    },

});;
Vue.component('signed-in-logo', {
    template: "#SIGNED_IN_LOGO_TEMPLATE",
    mixins:[MIXIN_MEMBERSHIP],
    data: function () {
        return {
            state: {
                loginStore: window.LoginStore.state
            }
        };
    },
    methods: {

    },
    computed: {
        memberInitials: function () {

            var initials = "";

            if (this.state.loginStore.membership) {

                if (this.state.loginStore.membership.FirstName != "" && this.state.loginStore.membership.FirstName != null) {
                    initials += this.state.loginStore.membership.FirstName[0];
                }
                if (this.state.loginStore.membership.LastName != "" && this.state.loginStore.membership.LastName != null) {
                    initials += this.state.loginStore.membership.LastName[0];
                }
            }

            //just put a default of M for Member
            if (initials == "") {
                initials = "M"
            }

            return initials;
        },
        membershipClass: function () {
            if (this.isHolidayPerksMember) {
                return "c-header__account--holiday";
            }
            else if (this.isPerksPlusMember) {
                return "c-header__account--plus";
            }
            else if (this.isVipPerksMember) {
                return "c-header__account--vip";
            }
        },
        memberType: function () {
            if (this.isHolidayPerksMember) {
                return "Holiday Perks";
            }
            else if (this.isPerksPlusMember) {
                return "Perks+";
            }
            else if (this.isVipPerksMember) {
                return "VIP Perks";
            }
        },
        memberNumber: function () {
            return this.state.loginStore.membership.Number;
        },
        memberCreated: function () {
            if (window.LoginStore.state.membership.Created.includes('Date')) {
                const ticks = Number(window.LoginStore.state.membership.Created.replace('/', '').replace('/', '').replace('Date(', '').replace(')', ''));
                return moment(new Date(ticks)).format('YYYY-MM-DD hh:mm:ss');
            }

            return moment(window.LoginStore.state.membership.Created).format('YYYY-MM-DD hh:mm:ss');
        }
    }
    
});;
Vue.component('member-benefits-card', {
    template: "#MEMBER_BENEFITS_CARD_TEMPLATE",
    props:["benefit"],
    data: function () {
        return {

        };
    },
    
   
});;
Vue.component('member-benefit-offer-code-widget', {
    template: "#MemberBenefitsOfferCodeWidgetTemplate",
    props: ["benefit", "has-code"],
    mixins: [MIXIN_MEMBERSHIP],
    data: function () {
        return {
            isLoading: false,
            offerCode: "",
            redeemLinkUrl: "",
            redeemLinkTitle: "",
            consumedLogin: false,
        };
    },
    methods: {
        addMembershipToCart: function () {
            var self = this;
            this.isLoading = true;
            window.CartEventBus.$emit(window.CartEvents.ADD_MEMBERSHIP, function () {
                self.isLoading = false;
            }, function (err) {
                self.isLoading = false;
                Common.ShowError("Unable to add membership to cart.")
            });
        },
        showSignInModal: function () {
            window.LoginEventBus.$emit(window.LoginEvents.SHOW_LOGIN_MODAL);
        },
        getOfferCode: function () {
            var self = this;
            self.isLoading = true;


            $.ajax({
                type: 'GET',
                method:'GET',
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                url: '/loyalty-club/OfferCode',
                data: { "documentId": self.benefit.DocumentID },
                success: function (response) {
                    self.isLoading = false;
                    self.offerCode = response.OfferCode;
                    self.redeemLinkTitle = response.RedeemLinkTitle;
                    self.redeemLinkUrl = response.RedeemLinkUrl;
                },
                error: function (xhr, statusText, err) {
                    self.isLoading = false;
                    Common.ShowError("Unable to retrieve offer code.");
                }
            });



            //self.offerCode = "NISS10OFF";
        },
    },
    computed: {
        showUpgradeButton: function () {
            return this.isHolidayPerksMember;
        },
        showOfferCode: function () {
            return this.offerCode.length > 0;
        },
        hasOfferCode: function ()
        {
            return this.hasCode;
        }

    },
    watch: {
        isLoggedIn: function () {
            var self = this;

            if (self.isLoggedIn && !this.isHolidayPerksMember) {
                self.getOfferCode();
            }

        }
    },
    mounted: function () {

        var self = this;

        //Check if we are already logged in as we first load the page
        if (self.isLoggedIn && !this.isHolidayPerksMember)
        {
            self.getOfferCode();
        }

        window.LoginEventBus.$on(window.LoginEvents.AUTHENTICATED, function () {
            if (self.isLoggedIn && !self.isHolidayPerksMember) {
                self.getOfferCode();
            }
        });
    }

});;
Vue.component('member-benefits-search', {
    template: "#MemberBenefitsSearchTemplate",
    data: function () {
        return {
            hasMoreBenefits: false,
            pageLoading: true,
            moreLoading: false,
            benefits: [],
            pageNumber: 1,
        };
    },
    methods: {
        loadMemberBenefits: function () {
            var self = this;

            var request = {
                PageNumber: self.pageNumber,
            };

            $.ajax({
                type: 'POST',
                url: '/api/search/MemberBenefits',
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {

                    self.pageLoading = false;
                    self.moreLoading = false;

                    self.benefits = self.benefits.concat(response.Benefits);
                    self.hasMoreBenefits = response.HasMoreBenefits;


                },
                error: function (xhr, statusText, err) {
                    self.pageLoading = false;
                    self.moreLoading = false;
                    Common.ShowError("Unexpected error trying to load search results.");
                }
            });

        },
        loadMoreMemberBenefits: function () {
            this.moreLoading = true;
            this.pageNumber++;
            this.loadMemberBenefits();
        }
    },
    mounted: function () {
        
        this.loadMemberBenefits();
    }
   
});;
Vue.component('add-membership-to-cart-wrapper', {
    data: function () {
        return {
           isLoading:false,
        };
    },
    methods: {
        addToCart: function () {
            var self = this;
            this.isLoading = true;
            window.CartEventBus.$emit(window.CartEvents.ADD_MEMBERSHIP, function () {
                self.isLoading = false;
            }, function (err) {
                self.isLoading = false;
                Common.ShowError(err);
            });
        },
        
    },
    
   
});;
Vue.component('membership-lookup-wrapper', {
    data: function() {
        return {
            isLoading: false,
            status: "",
            join: "",
        }
    },
    computed: {
        memberStatus: function ()
        {
            return this.status;
        },
        memberJoin: function ()
        {
            return this.join;
        },
    },
    methods: {
        lookupMember: function ()
        {
            var self = this;
            var memberNumber = document.getElementById('member_number').value;

            self.status = "";
            self.join = "";

            self.isLoading = true;

            if (memberNumber != null && memberNumber != "") {
                if (memberNumber.includes("M")) {
                    {
                        memberNumber = parseInt(memberNumber.replace("M", ""), 10);
                    }
                }
                var url = "/api/Partner/MemberLookup?memberNumber=" + memberNumber;

                $.ajax({
                    type: 'GET',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    success: function (response) {
                        self.isLoading = true;
                        self.status = response.MemberStatus;
                        self.join = moment(response.JoinDate).format("DD/MM/YYYY").toString();

                        self.isLoading = false;
                    },
                    error: function (xhr, statusText, err) {
                        Common.ShowError("Unexpected error trying to lookup member details deals.");
                    }
                });
            } else {
                Common.ShowError("Please enter the member number / barcode.");
            }

            self.isLoading = false;
        },
    }
});;
Vue.component('facilities-activities-data-wrapper', {

    props: ['items'],


    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {
            filterStore: window.FacilitiesActivitiesFilterStore.state
        }
    },
    watch: {
        categories: {
            handler: function (newValue) {
                this.$forceUpdate();
            },
            deep: true
        }
    },
    computed: {
        categories: function () {
            return this.filterStore.categories.values;
        },
        filteredItems: function () {

            var self = this;
            var filteredItemsToReturn = [];

            $.each(this.items, function (i, e) {
                if (self.IsAvailable(e)) {
                    filteredItemsToReturn.push(e);
                }

            });

            return filteredItemsToReturn;
        }
    },
    methods: {
        IsAvailable:function(item) {

            var self = this;
            
            var categoryKeys = Object.keys(this.filterStore.categories.values);

            if (categoryKeys.length > 0) {

                var categoriesSelected = [];
                $.each(categoryKeys, function (i, e) {
                    if (self.categories[e]) {
                        categoriesSelected.push(e);
                    }
                });


                if (categoriesSelected.length == 0) {
                    return true;
                }

                for (var i = 0; i < categoriesSelected.length; i++) {
                    if (categoriesSelected[i] == item.Category) {
                            return true;
                    
                    }
                }

                return false;

            }

            return true;
        },
    }

});
;
window.FacilitiesActivitiesFilterStore = {
    state: {
        categories: {
            values: {},
            tempValues: {}
        }
    },
    commitCategoriesFilter: function () {
        this.state.categories.values = JSON.parse(JSON.stringify(this.state.categories.tempValues));
    }

};
Vue.component('floor-plan-button', {

    
    props: [],
    template: '#FloorPlanTemplate',

    data: function () {
        return {}
    },
    methods: {

        
    },
    created: function () {

  
    }

});;
Vue.component('floor-plan-view', {


    props: ["floor-plan-url", "floor-plan-name"],

    data: function () {
        return {}
    },
    methods: {

        
    },
    computed:
    {
        planUrl: function ()
        {
            return this.floorPlanUrl;
        },

        planName: function ()
        {
            return this.floorPlanName
        }
    },
    created: function () {
        var data =
        {
            //TW: Change from hard coded value to take DocumentID
            documentID: DOCUMENT_ID
        }

        var self = this;

        $.ajax({
            type: 'GET',
            url: '/api/Park/GetFloorPlan/' + data.documentID,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (response) {
                self.floorPlanUrl = response.Url;
                self.floorPlanName = response.Name;
            },
            error: function (xhr, statusText, err) {
            }
        });
    }

});;
Vue.component('park-book-now', {

    
    props: [],
    template: '#PARK_BOOK_NOW',

    data: function () {
        return {
            menuPageYOffset: 0,
        }
    },
    methods: {
        updateData: function () {
            this.$data.menuPageYOffset = window.pageYOffset;
        }
    },
    computed:
    {
        isActive: function ()
        {
            return (this.$mq == 'sm' || this.$mq == 'md' || this.$mq == "lg")
        }
    },
    mounted: function ()
    {
        var self = this;
        window.addEventListener('scroll', function () {
            self.updateData();
        });
    }

});;
Vue.component('park-contact-form-wrapper', {

    data: function () {
        return {
            enquiry: '',
            firstName: '',
            lastName: '',
            email: '',
            mobile: '',
            message: '',
            pristine: null,
            isLoading: false,
            inProgress: true
        }
    },
    methods: {
        sendParkContactFormRequest: function () {
            var self = this;
            this.isLoading = true;

            //Validate form
            var validation = this.pristine.validate();

            //Send off request with relevant data if the form is valid
            if (validation) {

                var url = "/api/Park/SendContactForm";
                var request = {
                    Enquiry: this.enquiry,
                    FirstName: this.firstName,
                    LastName: this.lastName,
                    Email: this.email,
                    Mobile: this.mobile,
                    Message: this.message,
                    ParkID: window.PARK_BIG4ID,
                    CaptchaResponse: grecaptcha.getResponse()
                };

                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    data: JSON.stringify(request),
                    success: function (response) {
                        self.isLoading = false;

                        //check if the response is successful or not and display the correct thing to the screen
                        if (response.Status == 1) {
                            self.inProgress = false;
                        }
                        else {
                            Common.ShowError("An error occured when attempting to send the message");
                        }
                    },
                    error: function (xhr, statusText, err) {
                        self.isLoading = false;
                        Common.ShowError("An error occured when attempting to send the message");
                    }
                });
            }
            else {
                this.isLoading = false;
            }
        },
    },
    mounted: function () {
        this.pristine = new Pristine(this.$el, {
            classTo: "c-field",
            errorClass: 'has-error',
            successClass: 'is-success',
            errorTextParent: 'c-field',
            errorTextClass: 'c-field__error'
        }, true);
    }
  
  
});;
Vue.component('park-feature-icon', {

    props: ['featureId', 'feature-svg-url', 'feature-display-text'],

    template:'#ParkFeatureIconsTemplate',

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {}
    },
    computed: {
    },
    methods: {

    }

});
;
Vue.component('park-location-feature-icon', {

    props: ['locationFeatureId', 'location-display-text', 'location-svg-url'],

    template: '#ParkLocationFeatureIconTemplate',


    data: function () {
        return {}
    },
    computed: {
    },
    methods: {

    }

});
;
Vue.component('park-map-button', {

    
    props: [],
    template: '#ParkMapTemplate',

    data: function () {
        return {}
    },
    methods: {

        
    },
    created: function () {

  
    }

});;
Vue.component('park-pets-icon', {

    props: ['petsAllowed'],

    template:'#PetsAllowedTemplate',

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {}
    },
    computed: {
    },
    methods: {

    }

});
;
Vue.component('park-sticky-menu', {

    data: function () {
        return {
            menuPageYOffset: window.pageYOffset,
        }
    },
    computed:
    {
        isActive: function () {
            return (this.$data.menuPageYOffset > (document.getElementsByClassName('c-banner__body')[0].offsetTop + document.getElementsByClassName('c-banner__body')[0].offsetHeight) * 1.15);
        }
    },
    methods:
    {
        updateData: function () {
            this.$data.menuPageYOffset = window.pageYOffset;
        }
    },
    mounted: function () {
        var self = this;
        window.addEventListener('scroll', function () {
            self.updateData();
        });
    },
});;
Vue.component('price-table', {

    props: ['price-tiers', 'can-purchase'],
    mixins:[MIXIN_CART],
    template: '#PriceTableTemplate',
    data: function () {
        return {
            processing: false,
        }
    },
    computed: {
    },
    methods: {
        addDisabled: function () {
            
            if (!this.cartLoaded) {
                return true;
            }

            if (this.$refs.input) {
                for (var i = 0; i < this.$refs.input.length; i++) {
                    if (this.$refs.input[i].quantity > 0) {
                        return false;
                    }
                }
            }

            return true;
        },
        priceInteger:function(price) {

            var integer = Math.trunc(price);

            return integer;
        },
        priceDecimal:function(price) {

            var integer = Math.trunc(price);
            var dec = (price - integer).toString();

            var stringDec = ".00";
            if (dec.indexOf('.') > 0) {
                stringDec = dec.substring(dec.indexOf('.'));

                if (stringDec.length == 2) {
                    stringDec += "0";
                }
            }

            return stringDec
        },
        addToCart: function () {
            var self = this;
            var items = [];
            self.processing = true;

            $.each(this.$refs.input, function (i, e) {

                items.push({
                    ItemType: CartItemType.PRODUCT,
                    SKU: e.props.sku,
                    Quantity: e.quantity,
                });
            });

       

            window.CartEventBus.$emit(
                window.CartEvents.ADD_PRODUCTS,
                items,
                function () {
                    self.processing = false;
                },
                function () {
                    self.processing = false;
                });

        },
    },
    mounted: function () {
        var self = this;

        $.each(self.$refs.input, function (i, e) {
            e.$watch('quantity', function () {
                self.$forceUpdate();
            });
        });
        
    }

});
;
Vue.component('reviews', {
    
    /*
     * Initial state of the component's data.
     */

    data: function () {
        return {
            reviews: [],
            pageNumber: 0,
            resultsPerPage: 10,
            hasMoreReviews: true,
        }
    },
    
    methods: {
        formatReviewDate:function(item) {
            return moment(item.ReviewDate).format("DD MMM, YYYY");
        },
        getRating:function(item) {
            var ratingString = item.Rating.toFixed(1).toString();
            var ratingStringSet = ratingString.split(".");

            if (ratingStringSet[1] == "0") {
                return ratingStringSet[0];
            }
            else {
                return ratingString;
            }
        },
        getRatingPercent:function(item) {
            var percent = item.Rating * 100 / 10;
            //percent += "%";
            return percent;
        },
        checkMoreReviews: function () {
            return hasMoreReviews;
        },
        getReviewSourceImage:function(item) {
            var url = "";

            switch (item.ReviewSource.toLowerCase())
            {
                case "google":
                    url = "/Content/ReviewIcons/google_logo.png";
                    break;

                case ("ctrip (zh)"):
                    url = "/Content/ReviewIcons/ctrip_logo.png";
                    break;

                case ("booking"):
                    url = "/Content/ReviewIcons/booking_logo.png";
                    break;

                case ("wotif"):
                    url = "/Content/ReviewIcons/wotif_logo.png";
                    break;

                case ("expedia"):
                    url = "/Content/ReviewIcons/expedia_logo.png";
                    break;

                case ("agoda"):
                    url = "/Content/ReviewIcons/agoda_logo.png";
                    break;

                case ("facebook"):
                    url = "/Content/ReviewIcons/facebook_logo.png";
                    break;

                case ("turu"):
                    url = "/Content/ReviewIcons/turu_logo.png";
                    break;

                case ("hotels.com"):
                    url = "/Content/ReviewIcons/hotels_logo.jpg";
                    break;
            }
            if (url != "" || url != null) {
                return Common.CdnAssetUrl(url);
            }
            else {
                return "https://via.placeholder.com/60x60/333333";
            }
        },
        RetrieveReviews: function () {
            var self = this;

            this.pageNumber += 1;

            request = {
                ParkID: window.Big4ParkID,
                PageNumber: this.pageNumber,
                ResultsPerPage: this.resultsPerPage
            }

            var url = "/api/Reviews/GetReviews";
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    //self.reviews = response.Results;
                    self.reviews = self.reviews.concat(response.Results);
                    self.hasMoreReviews = response.HasMoreReviews;
                },
                error: function (xhr, statusText, err) {
                }
            });
        },
    },
    mounted: function () {
        this.RetrieveReviews();

        this.$on("LOAD-MORE-REVIEWS", function () {
            this.RetrieveReviews();
        });
    },

});
;
Vue.component("single-park-map-view-widget", {
    template: "#SINGLE_PARK_MAP_VIEW_TEMPLATE",
    props: ["park"],
    methods:
    {
        init: function () {
            new AzureMapSinglePin('map', { latitude: this.park.Latitude, longitude: this.park.Longitude }, 10);

        }
    },
    mounted: function () {
        this.init();
    }
});;
Vue.component('whats-local-data-wrapper', {

    //props: ['items'],


    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {
            filterStore: window.WhatsLocalFilterStore.state,
            items: [],
            memberItems: [],
            ATDWItems: []
        }
    },
    watch: {
        categories: {
            handler: function (newValue) {
                this.$forceUpdate();
            },
            deep: true
        }
    },
    computed: {
        categories: function () {
            return this.filterStore.categories.values;
        },
        //filteredItems() {

        //    var self = this;
        //    var filteredItemsToReturn = [];

        //    $.each(this.items, function (i, e) {
        //        if (self.IsAvailable(e)) {
        //            filteredItemsToReturn.push(e);
        //        }

        //    });

        //    return filteredItemsToReturn;
        //},
        SelectedCategories: function () {
            var self = this;
            var categoryKeys = Object.keys(this.filterStore.categories.values);

            var categoriesSelected = [];
            $.each(categoryKeys, function (i, e) {
                if (self.categories[e]) {
                    categoriesSelected.push(e);
                }
            });

            return categoriesSelected;

        },
    },
    methods: {

        //IsAvailable(item) {

        //    var self = this;
        //    if (item.DistanceFromPark > this.filterStore.distanceFromPark.value) {
        //        return false;
        //    }

        //    if (this.filterStore.memberBenefits.value) {
        //        if (!item.HasMemberBenefits) {
        //            return false;
        //        }
        //    }



        //    if (this.SelectedCategories.length == 0) {
        //        return true;
        //    }
        //    else {

        //        for (var i = 0; i < this.SelectedCategories.length; i++) {
        //            for (var j = 0; j < item.Categories.length; j++) {
        //                if (this.SelectedCategories[i] == item.Categories[j]) {
        //                    return true;
        //                }
        //            }
        //        }

        //        return false;
        //    }

        //    //return true;
        //},
        fetch: function () {

            var self = this;
            var url = "/api/Park/WhatsLocal";
            var request = {
                ParkDocumentID: PARK_DOCUMENT_ID,
                MaxDistance: this.filterStore.distanceFromPark.value,
                MemberOnly: this.filterStore.memberBenefits.value,
                Categories: this.SelectedCategories
            };

            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    // before setting the data source for the grid of tiles, we check to see if any of the links will
                    // return a 404 or not, if they would return a 404 then we demote the tile to just an image tile
                    // instead of a page linked tile
                    //for (var i = 0; i < response.ActivityProducts.length; i++) {
                    //    var activityProduct = response.ActivityProducts[i];

                    //    if (activityProduct.HasPage) { // check to see if this tile would link to a page or not
                    //        var request = false;

                    //        // create a request that will be used to test for 404
                    //        if (window.XMLHttpRequest) {
                    //            request = new XMLHttpRequest;
                    //        } else if (window.ActiveXObject) {
                    //            request = new ActiveXObject("Microsoft.XMLHttp");
                    //        }

                    //        if (request) {
                    //            // user created content and atdw pages are in the format './whats-local/name-identifier'
                    //            var itemUrl = window.location.href + '' + activityProduct.Url.replace('./whats-local', '');

                    //            // member benefits have an absolute url
                    //            if (activityProduct.Url.indexOf('://') > 0) {
                    //                itemUrl = activityProduct.Url;
                    //            }

                    //            // attach our tile object to the request so we can process it once it has been loaded
                    //            request.ActivityProduct = activityProduct;

                    //            // handle the event for once the request has completed
                    //            request.onload = function (e) {
                    //                

                    //                if (e.currentTarget.status != 200) {
                    //                    e.currentTarget.ActivityProduct.HasPage = false;
                    //                }
                    //            }

                    //            // send the request
                    //            request.open("GET", itemUrl);
                    //            request.send();
                    //        }
                    //    }
                    //}

                    self.items = response.ActivityProducts;
                    self.memberItems = response.MemberBenefitActivityProducts;
                    self.ATDWItems = response.ATDWActivityProducts;

                },
                error: function (xhr, statusText, err) {
                }
            });
        }
    },

    created: function () {
        this.fetch();
    },
    mounted: function () {
        var self = this;
        window.FilterEventBus.$on(window.FilterEvents.UPDATE_FILTERS, function () {
            self.fetch();
        });
    }

});
;
window.WhatsLocalFilterStore = {
    state: {
        memberBenefits: {
            value: false,
            tempValue: false,
        },
        distanceFromPark: {
            value: 50,
        },
        categories: {
            values: {},
            tempValues: {}
        }
    },

    commitMemberBenefits: function () {
        this.state.memberBenefits.value = this.state.memberBenefits.tempValue;
        window.FilterEventBus.$emit(window.FilterEvents.UPDATE_FILTERS);
    },
    commitDistanceFromPark:function(val) {
        this.state.distanceFromPark.value = val;
        window.FilterEventBus.$emit(window.FilterEvents.UPDATE_FILTERS);
    },
    commitCategoriesFilter: function () {
        this.state.categories.values = JSON.parse(JSON.stringify(this.state.categories.tempValues));
        window.FilterEventBus.$emit(window.FilterEvents.UPDATE_FILTERS);
    }

};
Vue.component("park-directory-map", {
    template: "#PARK_DIRECTORY_MAP_TEMPLATE",
    props: ["parks"],
    data: function ()
    {
        return {
            markersArray: [],
        }
    },
    methods:
    {
        init: function () {

            new AzureMapWithClusteredParkMarkers('map', this.parks);
        }
    },
    mounted: function ()
    {
        this.init();
    }
});;
window.PetFriendlyEventBus = new Vue();
window.Iteration = 0;;
Vue.component('pet-friendly-parks', {

    /*
     * Initial state of the component's data.
     */

    data: function () {
        return {
            parks: [],
            pageNumber: 0,
            stateList: [],
            endOfList: false,
            i: 0,
            loading: true,
        }
    },

    methods: {
        getPetFriendlyParks: function () {
            this.loading = true;
            var self = this;

            self.pageNumber += 1;

            var request = {
                StateList: this.stateList,
                PageNumber: this.pageNumber
            };

            var url = "/api/PetFriendlyLandingPage/GetPetFriendlyParks";
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    self.parks = self.parks.concat(response.Parks);
                    self.endOfList = response.EndOfList;
                    self.loading = false;
                },
                error: function (xhr, statusText, err) {
                    self.loading = false;
                }
            });
        },
        bindFilterEvents: function () {
            var self = this;
            window.PetFriendlyEventBus.$on('state-filter-update', function (data) {
                self.parks = [];
                self.stateList = [];
                self.endOfList = false;
                self.pageNumber = 0;

                for (i = 0; i < data.length; i++) {
                    self.stateList[i] = data[i];
                }

                self.getPetFriendlyParks();
            });
        }
    },
    mounted: function () {
        var self = this;
        self.bindFilterEvents();
        self.getPetFriendlyParks();
    },

});
;
Vue.component('state-pet-friendly-parks', {
    props: ["stateCode"],
    data: function () {
        return {
            parks: [],
            pageNumber: 0,
            stateList: [],
            endOfList: false,
            i: 0,
            loading: true,
        }
    },

    methods: {
        getStatePetFriendlyParks: function () {
            this.loading = true;
            var self = this;

            this.pageNumber += 1;

            request = {
                StateList: this.stateList,
                PageNumber: this.pageNumber
            }

            var url = "/api/PetFriendlyStatePage/GetPetFriendlyParksForState";
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    self.parks = self.parks.concat(response.Parks);
                    self.endOfList = response.EndOfList;
                    self.loading = false;
                },
                error: function (xhr, statusText, err) {
                    self.loading = false;
                }
            });
        }
    },
    mounted: function () {
        var self = this;
        self.stateList = [this.stateCode];
        self.getStatePetFriendlyParks();
    },

});;
Vue.component('my-account-stack-menu', {
    template: '#MyAccountstackMenuTemplate',
    props: ['class-list', 'current-menu', 'location'],
    data: function () {
        return {
            state: {
                loginStore: window.LoginStore.state,
            },
            items: [],
            isActive: false,
        }
    },
    computed: {
        isLoggedIn: function () {
            if (this.state.loginStore.membership) {
                if (this.state.loginStore.membership.MemberID) {
                    if (document.getElementById('SignInPrompt') != undefined)
                    {
                        document.getElementById('SignInPrompt').style.display = "none";
                    }
                    return true;
                }
            }

            return false;
        },
        props: function() {
            return {
                currentMenu: this.currentMenu,
            };
        },
    },
    mounted: function () {
        var self = this;
        //Auto display the sign in modal if the user hits the my account page without signing in
        if (!this.isLoggedIn && window.location.href.includes("/myaccount")) {
            document.getElementById('SignInPrompt').style.display = "inherit";
            window.LoginStore.showSignInModal();
        }
    }
});
;
Vue.component('any-type-of-stay-widget', {
    props: ["categories"],
    data: function () {
        return {
            categoryList: [],
            loading: true,
        }
    },
    computed:
    {
        IsLoading: function () {
            return this.loading;
        }
    },
    methods: {
    },
    mounted: function () {
        var self = this;
        self.categoryList = this.categories;

        self.loading = false;
    },

});;
if (typeof(IdListPickerManager) !== typeof(undefined)) {
    var idPickerManager = IdListPickerManager.getInstance();
    idPickerManager.LoadTreeNavigation(jsTreeID, jsTreeBodyID, jsTreeFormID, tempInputID, dealsValue);
};
if (typeof(IdListPickerManager) !== typeof(undefined)) {
    var idPickerManager = IdListPickerManager.getInstance();
    idPickerManager.LoadTreeNavigation(jsTreeID, jsTreeBodyID, jsTreeFormID, tempInputID);
};
if (typeof (LinkPickerManager) !== typeof (undefined)) {
    var linkPickerManager = LinkPickerManager.getInstance();
    linkPickerManager.LoadTreeNavigation(jsTreeID, jsTreeBodyID, jsTreeFormID, tempInputID);
};
Vue.component('marketing-deal-cards-widget', {
    props: ["deals"],
    data: function () {
        return {
            displayDeals: [],
            pageNumber: 1,
            dealList: [],
            endOfList: false,
            i: 0,
            loading: true,
        }
    },

    methods: {
        getNextPage: function () {
            var self = this;
            self.pageNumber++;

            self.displayDeals = self.dealList.slice(0, self.pageNumber * 24);

            if (self.dealList.length <= (self.pageNumber * 24)) {
                self.endOfList = true;
            }
        }
    },
    mounted: function () {
        var self = this;
        self.dealList = this.deals;
        console.log(this);

        for (var i = self.dealList.length - 1; i >= 0; i--) {
            if (self.dealList[i].ImageUrl == null || self.dealList[i].ImageUrl == undefined || self.dealList[i].ImageUrl == '') {
                self.dealList.splice(i, 1);
            }
        }

        self.displayDeals = self.dealList.slice(0, 24);

        if (self.dealList.length <= 24) {
            self.endOfList = true;
        }

        self.loading = false;
    },

});;
Vue.component('marketing-park-cards-widget', {
    props: ["parks"],
    data: function () {
        return {
            displayParks: [],
            pageNumber: 1,
            parkList: [],
            endOfList: false,
            i: 0,
            loading: true,
        }
    },

    methods: {
        getNextPage: function () {
            var self = this;
            self.pageNumber++;

            self.displayParks = self.parkList.slice(0, self.pageNumber * 24);

            if (self.parkList.length <= (self.pageNumber * 24)) {
                self.endOfList = true;
            }
        }
    },
    mounted: function () {
        var self = this;
        self.parkList = this.parks;

        for (var i = self.parkList.length - 1; i >= 0; i--) {
            if (self.parkList[i].Images == null || self.parkList[i].Images == undefined || self.parkList[i].Images.length == 0) {
                self.parkList.splice(i, 1);
            }
        }

        self.displayParks = self.parkList.slice(0, 24);
        
        if (self.parkList.length <= 24) {
            self.endOfList = true;
        }

        self.loading = false;
    },

});;
Vue.component('on-your-doorstep-widget', {
    props: ["parks", "categories"],
    data: function () {
        return {
            parkList: [],
            displayParks: [],
            categoryList: [],
            loading: true,
            currentCategoryId: 1,
            selectedState: ''
        }
    },
    computed:
    {
        CurrentCategory: function () {
            return this.currentCategoryId;
        },
        BackgroundImageUrl: function () {
            var self = this;

            for (var i = 0; i < self.categoryList; i++) {
                if (self.categoryList[i].CategoryID == currentCategoryId) {
                    return self.categoryList[i].BackgroundImageUrl
                }
            }
        },
        CurrentCategoryName: function () {
            var self = this;

            for (var i = 0; i < self.categoryList.length; i++) {
                if (self.categoryList[i].CategoryID == self.currentCategoryId) {
                    return self.categoryList[i].Name;
                }
            }
        },
        CurrentCategoryDescription: function () {
            var self = this;

            for (var i = 0; i < self.categoryList.length; i++) {
                if (self.categoryList[i].CategoryID == self.currentCategoryId) {
                    return self.categoryList[i].Description;
                }
            }
        },
        IsLoading: function () {
            return this.loading;
        }
    },
    methods: {
        HasIncludedLocation: function (park, categoryId) {
            var self = this;
            var currentLocationList = [];

            if (categoryId !== undefined) {
                currentLocationList = self.categoryList.filter(function (x) { return x.CategoryID == categoryId })[0].IncludedLocationFeatureIDs;
            } else {
                currentLocationList = self.categoryList.filter(function (x) { return x.CategoryID == self.currentCategoryId })[0].IncludedLocationFeatureIDs;
            }

            if (currentLocationList.length > 0) {
                if (currentLocationList.indexOf(park.LocationCategoryID) >= 0) {
                    return true;
                }
            }


            return false;
        },
        HasIncludedParkFeature: function (park, categoryId) {
            var self = this;
            var currentFeaturesList = [];

            if (categoryId !== undefined) {
                currentFeaturesList = self.categoryList.filter(function (x) { return x.CategoryID == categoryId })[0].IncludedParkFeatureIDs;
            } else {
                currentFeaturesList = self.categoryList.filter(function (x) { return x.CategoryID == self.currentCategoryId })[0].IncludedParkFeatureIDs;
            }

            if (currentFeaturesList.length > 0) {
                for (var i = 0; i < park.ParkFeatureCategoryIDs.length; i++) {
                    if (currentFeaturesList.indexOf(park.ParkFeatureCategoryIDs[i]) >= 0) {
                        return true;
                    }
                }
            }

            return false;
        },
        HasExcludedFeature: function (park, categoryId) {
            var self = this;
            var excludedLocationList = [];
            var excludedParkFeatureList = [];

            if (categoryId !== undefined) {
                excludedLocationList = self.categoryList.filter(function (x) { return x.CategoryID == categoryId })[0].ExcludedLocationFeatureIDs;
                var excludedParkFeatureList = self.categoryList.filter(function (x) { return x.CategoryID == categoryId })[0].ExcludedParkFeatureIDs;
            } else {
                excludedLocationList = self.categoryList.filter(function (x) { return x.CategoryID == self.currentCategoryId })[0].ExcludedLocationFeatureIDs;
                excludedParkFeatureList = self.categoryList.filter(function (x) { return x.CategoryID == self.currentCategoryId })[0].ExcludedParkFeatureIDs;
            }

            if (excludedLocationList.length > 0) {
                if (excludedLocationList.indexOf(park.LocationCategoryID) >= 0) {
                    return true;
                }
            }

            if (excludedParkFeatureList.length > 0) {
                for (var i = 0; i < park.ParkFeatureCategoryIDs.length; i++) {
                    if (excludedParkFeatureList.indexOf(park.ParkFeatureCategoryIDs[i]) >= 0) {
                        return true;
                    }
                }
            }

            return false;
        },
        UpdateDisplayParks: function () {
            var self = this;
            var parks = [];

            for (var i = 0; i < self.parkList.length; i++) {
                if ((self.HasIncludedLocation(self.parkList[i]) || self.HasIncludedParkFeature(self.parkList[i])) && !self.HasExcludedFeature(self.parkList[i])) {
                    parks.push(self.parkList[i]);
                }
            }

            if (self.selectedState !== undefined && self.selectedState.length > 0) {
                parks = parks.filter(function (x) { return x.ParkCard.StateCode == self.selectedState });
            }

            //Put in fcom parks
            for (var i = 0; i < parks.length; i++) {
                if (!parks[i].AffiliatePark) {
                    self.displayParks.push(parks[i].ParkCard);
                }
            }

            //Put in affiliate parks
            for (var i = 0; i < parks.length; i++) {
                if (parks[i].AffiliatePark) {
                    self.displayParks.push(parks[i].ParkCard);
                }
            }
        },
        CheckCategoryIsEmpty: function (categoryId) {
            var self = this;
            var parks = [];
            for (var i = 0; i < self.parkList.length; i++) {
                if ((self.HasIncludedLocation(self.parkList[i], categoryId) || self.HasIncludedParkFeature(self.parkList[i], categoryId)) && !self.HasExcludedFeature(self.parkList[i], categoryId)) {
                    parks.push(self.parkList[i]);
                }
            }

            if (self.selectedState !== undefined && self.selectedState.length > 0) {
                parks = parks.filter(function (x) { return x.ParkCard.StateCode == self.selectedState });
            }

            return parks.length == 0;
        },
        UpdateCurrentCategory: function (categoryId) {
            var self = this;
            self.loading = true;

            self.displayParks = [];
            self.currentCategoryId = categoryId;
            self.UpdateBackgroundImage();
            self.UpdateDisplayParks();

            self.loading = false;
        },
        RefreshParks: function () {
            var self = this;
            self.loading = true;

            self.displayParks = [];
            self.UpdateDisplayParks();

            self.loading = false;
        },
        UpdateBackgroundImage: function () {
            var self = this;

            for (var i = 0; i < self.categoryList.length; i++) {
                if (self.categoryList[i].CategoryID == self.currentCategoryId) {
                    document.getElementById("backgroundImage").src = self.categoryList[i].BackgroundImageUrl;
                }
            }
        }
    },
    mounted: function () {
        var self = this;
        self.parkList = this.parks;
        self.categoryList = this.categories;

        self.UpdateCurrentCategory(self.categoryList[0].CategoryID);

        //If we don't have anything to display on the first category, then we want to swap to the first category with parks
        if (self.displayParks.length == 0) {
            for (var i = 1; i < self.categoryList.length; i++) {
                self.UpdateCurrentCategory(self.categoryList[i].CategoryID);
            }

            if (self.displayParks.length > 0) {
                i = self.categoryList.length;
            }
        }

        self.loading = false;
    },

});;
window.SearchResultsAndFiltersEventBus = new Vue();

window.SearchResultsAndFiltersEvents = {
    GET_AVAILABILITY: "get-availability",
    SUBSCRIBE_TO_SIGNALR: "subscribe-to-signalr",
    UNSUBSCRIBE_FROM_SIGNALR: "unsubscribe-from-signalr",
    SIGNALR_CONNECTED: "signalr-connected",
};;
Vue.component("search-results-and-filters-map", {
    template: "#SEARCH_MAP_TEMPLATE",
    props: ["parks"],
    data: function () {
        return {
            markersArray: [],
        }
    },
    methods:
    {
        init: function () {

            //TW: Basic initialisation for google maps
            var uluru = { lat: -25.363, lng: 131.044 };
            
            window.searchMap = new google.maps.Map(document.getElementById('map'), {
                zoom: 4,
                center: uluru
            });
            
            window.searchMapInfowindow = new google.maps.InfoWindow({
                content: "",
            });

            if (this.parks.length > 0 && this.parks.length != this.markersArray)
            {
                this.addParks();
            }

            this.clusterMarkers();
        },
        addParks: function ()
        {
            //Takes previously generated map and adds new markers based on search results

            //Clear all markers from the map first
            if (this.markersArray.length > 0) {
                for (var i = 0; i < this.markersArray.length; i++) {
                    this.markersArray[i].setMap(null);
                }
            }

            var parkResults = window.SearchResultsAndFiltersWidgetStore.state.ParkSearch.FilterResults;
            var searchLatLngBounds = new google.maps.LatLngBounds();

            //used for map boundary and zoom
            var googleLatLng = [];

            for (var i = 0; i < parkResults.length; i++) {
                var park = { lat: parkResults[i].Latitude, lng: parkResults[i].Longitude };


                var marker = new google.maps.LatLng(parkResults[i].Latitude, parkResults[i].Longitude);
                googleLatLng.push(marker);

                //TW: Custom map marker icon svg information
                var icon =
                {
                    path: "M16 32c7.6-8.2 11.8-13.5 11.8-20.1s-5.3-11.9-11.8-11.9-11.8 5.3-11.8 11.9 4.1 11.9 11.8 20.1zM16 6.7c2.8 0 5.1 2.3 5.1 5.1s-2.3 5.1-5.1 5.1-5.1-2.3-5.1-5.1 2.3-5.1 5.1-5.1z",
                    fillColor: "#0064b6",
                    fillOpacity: 1.0,
                    anchor: new google.maps.Point(16, 32),
                    strokeWeight: 0,
                    scale: 1
                }

                var marker = new google.maps.Marker({
                    position: park,
                    map: window.searchMap,
                    title: parkResults[i].ParkName,
                    icon: icon,
                    review: parkResults[i].ReviewRating,
                    typeID: parkResults[i].ParkTypeID,
                    image: parkResults[i].Images[0],
                    page: parkResults[i].Url,
                });

                //Put the marker into our markersArray so that we can delete it later if necessary
                this.markersArray.push(marker);

                google.maps.event.addListener(marker, 'click', function () {

                    var imgString = "";
                    var parkBadgeString = "";
                    var reviewString = "";

                    //TW: switch for generating park badge based off of type
                    switch (this.typeID) {
                        case (window.Enums.ParkTypeEnum["Affiliate"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-bullet-rounded c-icon--tertiary-accent"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="227" height="32" viewBox="0 0 227 32"><title>badge-bullet-rounded</title> <path d="M-0.012 3.563c0-4.874 69.747-2.011 98.196-2.011s105.767 2.011 115.202 2.011c9.437 0 29.334 27.599-11.15 27.599-40.483 0-169.104 0.273-185.676 0s-16.572-3.135-16.572-27.599z"></path></svg></span></div> <p class="c-badge__label">Affiliate</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMHoliday"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-3 c-icon--primary"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="136" height="32" viewBox="0 0 136 32"><title>badge-holiday</title> <path d="M0.879 2.702c1.916-4.48 35.716-2.037 42.326-2.037s67.99 0.646 78.154 0.646c10.165 0 31.658 29.085-11.946 29.085-43.605 0-67.97 1.604-90.122 1.604-22.151 0-18.413-12.376-18.413-29.298z"></path></svg></span></div> <p class="c-badge__label">Holiday</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMClassic"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-1 c-icon--callout-variant-two"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="132" height="32" viewBox="0 0 132 32"><title>badge-trapezoid-1</title> <path d="M0.077 0.649c27.028-0.555 38.893 0 68.8 0s56.662 2.811 55.373 2.811c-1.289 0 26.849 26.363-15.713 26.363-42.559 0-72.196 1.774-91.23 1.774s-17.322-4.022-17.231-30.948z"></path></svg></span></div> <p class="c-badge__label">Classic</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMPremier"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-2 c-icon--callout-variant-one"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="135" height="32" viewBox="0 0 135 32"><title>badge-trapezoid-2</title> <path d="M0.031 2.025c17.082-1.098 27.529-1.496 41.797-1.496 14.267 0 67.371-0.268 80.033 4.578 12.665 4.845 27.686 26.365-16.198 26.365h-87.823c-19.403 0-17.809-8.562-17.809-29.448z"></path></svg></span></div> <p class="c-badge__label">Premier</p></span></div>';
                            break;
                        case (window.Enums.ParkTypeEnum["Legacy"]):
                            break;

                    }

                    if (this.image != null && !this.image.MapsImageUrl.includes("placehold")) {
                        imgString = '<img style="width:100%" srcset="' + this.image.MapsImageUrl + ' 300w" sizes="(min-width: 1024px) 20vw,(min-width: 768px) 30vw,30vw" src="' + this.image.MapsImageUrl + '" alt="">'
                    } else {
                        imgString = '<img srcset="https://placehold.it/280x158 280w,https://placehold.it/300x169 300w,https://placehold.it/300x169 300w" sizes="(min-width: 1024px) 20vw,(min-width: 768px) 30vw,30vw" src="https://placehold.it/300x169" alt="">'
                    }

                    if (this.review != null && this.review > 0) {
                        reviewString = '<div class="c-ratings"><span><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns: xlink="http://www.w3.org/1999/xlink" width="30" height="32" viewBox="0 0 30 32" class="svg-defs" style="position: absolute; width: 0px; height: 0px;"><clipPath id="star"><path d="M29.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.3,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6\
                                        c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C0.1,11.5,0,11.2,0,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C14.2,0.2,14.5,0,14.9,0s0.6,0.2,0.9,0.7	l4,8.1l9,1.3C29.4,10.3,29.7,10.5,29.7,11z"></path>\
                                        <path d="M64.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C35.1,11.5,35,11.2,35,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C49.2,0.2,49.5,0,49.9,0	s0.6,0.2,0.9,0.7l4,8.1l9,1.3C64.4,10.3,64.7,10.5,64.7,11z"></path>\
                                        <path d="M99.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C70.1,11.5,70,11.2,70,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C84.2,0.2,84.5,0,84.9,0\
                                        c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C99.4,10.3,99.7,10.5,99.7,11z"></path><path d="M134.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	\
                                        c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C134.4,10.3,134.7,10.5,134.7,11z"></path><path d="M169.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3s-0.2-0.4-0.2-0.6c0-0.1,0-0.2,0-0.4	l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7s0.6,0.2,0.9,0.7l4,8.1l9,1.3	C169.4,10.3,169.7,10.5,169.7,11z"></path></clipPath><clipPath id="star-empty">\
                                        <path d="M29.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.3,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C0.1,11.5,0,11.2,0,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C14.2,0.2,14.5,0,14.9,0s0.6,0.2,0.9,0.7	l4,8.1l9,1.3C29.4,10.3,29.7,10.5,29.7,11z"></path>\
                                        <path d="M64.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C35.1,11.5,35,11.2,35,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C49.2,0.2,49.5,0,49.9,0	s0.6,0.2,0.9,0.7l4,8.1l9,1.3C64.4,10.3,64.7,10.5,64.7,11z"></path>\
                                        <path d="M99.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C70.1,11.5,70,11.2,70,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C84.2,0.2,84.5,0,84.9,0	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C99.4,10.3,99.7,10.5,99.7,11z"></path>\
                                        <path d="M134.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C134.4,10.3,134.7,10.5,134.7,11z"></path>\
                                        <path d="M169.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3s-0.2-0.4-0.2-0.6c0-0.1,0-0.2,0-0.4	l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7s0.6,0.2,0.9,0.7l4,8.1l9,1.3	C169.4,10.3,169.7,10.5,169.7,11z"></path></clipPath><rect id="rating" width="120" height="30" clip-path="url(#star)"></rect></svg>\
                                        <span class="rating-eg"><svg height="12px" viewBox="0 0 170 30" data-rating="1.2" class="rating"><rect x="0" y="0" width="100%" height="100%" clip-path="url(#star-empty)" class="bg-rect" style="fill: rgb(236, 236, 236);"></rect><rect x="0" y="0" width="'+ this.review * 10 + '%" height="100%" clip-path="url(#star)" class="rating-rect" style="fill: rgb(55, 55, 55);"></rect></svg></span></span> <strong class="u-p4">' + Math.round(this.review * 10) / 10 + '/10</strong></div>'
                            ;
                    } else {
                        reviewString = '<strong class="u-p4" style="padding-left: 10px;">No reviews yet</strong>';
                    }


                    //TW: This is the html that will generate the park card structure for the google maps infowindow.
                    //We pass in the above generated strings for images and park badge. We also do calculations for ratings here
                    var contentString = '<div class="infoWindow">\
                         <div class="styleguide-maps" style="background-image: ' + "url('" + +"');" + ' " data-component="location-map-container" data-component-context="Location Pages">\
                         <div class="styleguide-maps__card d-none d-md-block">\
                        <div class="styleguide-maps__card d-none d-md-block"><div data-component="park-card" data-component-context="map" data-component-label="BIG4 Beacon Resort" class="c-card c-card--primary c-card--popup"><div class="c-card__gallery">'
                        + '<a href = "' + this.page + '" class="c-card__img-wrapper"> '
                        + imgString
                        + '</a>'
                        + parkBadgeString
                        + '</div >'
                        + '<div class="c-card__body"> <h3 class="u-h6 c-card__title"><a href="' + this.page + '">'
                        + this.title + '</a ></h3 >'
                        + reviewString
                        + '</div>\
                        </div>\
                       </div>';
                    window.searchMapInfowindow.setContent(contentString);
                    window.searchMapInfowindow.open(window.searchMap, this);
                });
               
            }

            //TW: Fits the map zoom around the markers by default
            for (var i = 0; i < googleLatLng.length; i++)
            {
                searchLatLngBounds.extend(googleLatLng[i]);
            }
            window.searchMap.fitBounds(searchLatLngBounds);
        },
        clusterMarkers: function ()
        {
            window.markerCluster = new MarkerClusterer(window.searchMap, this.markersArray, { imagePath: '/Content/Images/GoogleMaps/markerclusterer/images/m' });
        },
        reloadMap: function () {
            this.markersArray = [];
        }
    },
    mounted: function ()
    {
        this.init();
    },
});;
Vue.component('search-results-and-filters-widget', {
    props: ["term", "editMode"],
    data: function () {
        return {
            loading: false,
            moreParksLoading: false,
            currentPage: 1,
            resultsPerPage: 12,
            hasMoreParks: false,
            searchTerm: '',
            totalNumResults: 0,
            store: window.SearchResultsAndFiltersWidgetStore,
            websiteHub: null,
            signalRConnected: false,
            subscribers: [],
            defaultPetFriendly: true,
            markersArray: [],
            unavailableParks: [],
            parkMap: null,
        }
    },
    computed:
    {
        IsLoading: function () {
            return this.loading;
        },
        MoreParksLoading: function () {
            return this.moreParksLoading;
        },
        ParkResults: function () {
            return this.store.state.ParkSearch.Results;
        },
        DisplayParks: function () {
            return this.store.state.ParkSearch.FilterResults;
        }
    },
    methods: {
        initSignalR: function () {
            var self = this;
            if (this.websiteHub == null) {
                //do the signalr initialisation
                this.websiteHub = $.connection.websiteHub;
                this.websiteHub.client.priceUpdate = this.processSignalRResponse;
                //$.connection.hub.start();

                $.connection.hub.start().done(function () {
                    self.signalRConnected = true;
                    window.SearchResultsAndFiltersEventBus.$emit(window.SearchResultsAndFiltersEvents.SIGNALR_CONNECTED);
                });
            }
        },
        processSignalRResponse: function (data) {
            var self = this;
            //get the responses from signal r
            var parkID = 0;
            if (data.AllAccommodations.length > 0) {
                parkID = data.AllAccommodations[0].ParkID;

                for (var i = 0; i < this.subscribers.length; i++) {
                    if (this.subscribers[i].parkId == parkID) {
                        this.subscribers[i].updatePrice(data);

                        break;
                    }
                }
            }
        },
        subscribe: function (park) {

            //if the subscriber isn't already subscribed
            if (!_.some(this.subscribers, { ParkID: park.ParkID })) {
                this.subscribers.push(park);
            }
        },
        unsubscribe: function (park) {
            for (var i = 0; i < this.subscribers.length; i++) {
                if (this.subscribers[i].parkID == park.parkID) {
                    this.subscribers.splice(i, 1);
                }
            }
        },
        doSignalR: function () {
            if (this.store.state.FiltersChanged) { return true; }
            else if (this.store.state.DEFAULT_ADULTS != this.store.state.NumAdults) { return true; }
            else if (this.store.state.DEFAULT_CHILDREN != this.store.state.NumChildren) { return true; }
            else if (this.store.state.DEFAULT_INFANTS != this.store.state.NumInfants) { return true; }
            else if (!this.store.state.DEFAULT_START_DATE.isSame(this.store.state.StartDate)) { return true; }
            else if (!this.store.state.DEFAULT_END_DATE.isSame(this.store.state.EndDate)) { return true; }

            return false;
        },
        updatePricesFromPms: function () {
            if (this.doSignalR()) {
                //we want to call SignalR for the parks we have just retrieved.
                var parkAvailabilityRequest =
                {
                    "ArrivalDate": moment(this.store.state.StartDate).format("YYYY-MM-DD"),
                    "DepartingDate": moment(this.store.state.EndDate).format("YYYY-MM-DD"),
                    "NumAdults": this.store.state.NumAdults,
                    "NumKids": this.store.state.NumChildren,
                    ParkIDs: []
                };

                for (var i = 0; i < this.subscribers.length; i++) {
                    this.subscribers[i].setPriceLoading();
                    parkAvailabilityRequest.ParkIDs.push(this.subscribers[i].parkId);
                }

                window.SearchResultsAndFiltersEventBus.$emit(window.SearchResultsAndFiltersEvents.GET_AVAILABILITY, parkAvailabilityRequest);
            }
        },
        updatePricesFromPmsForParkList: function (parkIdList) {
            if (this.doSignalR() && parkIdList.length > 0) {
                //we want to call SignalR for the parks we have just retrieved.
                var parkAvailabilityRequest =
                {
                    "ArrivalDate": moment(this.store.state.StartDate).format("YYYY-MM-DD"),
                    "DepartingDate": moment(this.store.state.EndDate).format("YYYY-MM-DD"),
                    "NumAdults": this.store.state.NumAdults,
                    "NumKids": this.store.state.NumChildren,
                    ParkIDs: []
                };

                for (var i = 0; i < this.subscribers.length; i++) {
                    if (parkIdList.indexOf(this.subscribers[i].parkId) >= 0) {
                        this.subscribers[i].setPriceLoading();
                        parkAvailabilityRequest.ParkIDs.push(this.subscribers[i].parkId);
                    }
                }

                window.SearchResultsAndFiltersEventBus.$emit(window.SearchResultsAndFiltersEvents.GET_AVAILABILITY, parkAvailabilityRequest);
            }
        },
        bindFilterEvents: function () {
            var self = this;

            window.SearchResultsAndFiltersEventBus.$on('date-filter-update', function (data) {

                //WM - This widget is set up slightly different so we need to change how we check if this is using the default dates or not
                var defaultStart = (window.SearchResultsAndFiltersWidgetStore.state.DEFAULT_START_DATE.month() + 1) + "/" + window.SearchResultsAndFiltersWidgetStore.state.DEFAULT_START_DATE.date() + "/" + window.SearchResultsAndFiltersWidgetStore.state.DEFAULT_START_DATE.year();
                var defaultEnd = (window.SearchResultsAndFiltersWidgetStore.state.DEFAULT_END_DATE.month() + 1) + "/" + window.SearchResultsAndFiltersWidgetStore.state.DEFAULT_END_DATE.date() + "/" + window.SearchResultsAndFiltersWidgetStore.state.DEFAULT_END_DATE.year();
                if (data.start.toLocaleDateString() !== defaultStart &&
                    data.end.toLocaleDateString() !== defaultEnd) {
                    window.SearchResultsAndFiltersWidgetStore.state.dateFilterApplied = true;
                } else {
                    window.SearchResultsAndFiltersWidgetStore.state.dateFilterApplied = false;
                }

                if (window.SearchResultsAndFiltersWidgetStore.state.dateFilterApplied == true) {
                    self.store.state.StartDate = data.start;
                    self.store.state.EndDate = data.end;
                    self.store.state.FiltersChanged = true;

                    //Reload the search results with the new dates
                    self.performParkSearch();

                } else {
                    self.store.state.StartDate = self.store.state.DEFAULT_START_DATE;
                    self.store.state.EndDate = self.store.state.DEFAULT_END_DATE;
                    self.store.state.FiltersChanged = true;
                    //self.updatePricesFromPms();
                }

            });

            window.SearchResultsAndFiltersEventBus.$on('guest-filter-update', function (data) {
                var oldValue = { adults: self.store.state.NumAdults, children: self.store.state.NumChildren, infants: self.store.state.NumInfants };
                self.store.state.NumAdults = data.adults;
                self.store.state.NumChildren = data.children;
                self.store.state.NumInfants = data.infants;
                self.store.state.FiltersChanged = true;
                var newValue = { adults: self.store.state.NumAdults, children: self.store.state.NumChildren, infants: self.store.state.NumInfants };

                var changed = newValue.adults != oldValue.adults || newValue.children != oldValue.children || newValue.infants != oldValue.infants;

                if (self.subscribers.length === 0 && changed) {
                    window.SearchResultsAndFiltersEventBus.$once("park-results-updated", function () {
                        //we need to postpone this for the initial load, so it doesn't happen until the parks are all subscribed
                        self.updatePricesFromPms();
                    });
                }
                else if (changed) {
                    self.updatePricesFromPms();
                }

            });

            window.SearchResultsAndFiltersEventBus.$on('pets-filter-update', function (data) {
                var oldValue = self.store.state.PetFriendly;
                self.store.state.PetFriendly = data.isOn;
                self.store.state.FiltersChanged = true;

                var changed = self.store.state.PetFriendly != oldValue;

                if (self.store.state.ParkSearch.Results.length > 0 && changed) {
                    self.setDisplayParks(false);
                }
            });

            window.SearchResultsAndFiltersEventBus.$on('availability-filter-update', function (data) {
                var oldValue = self.store.state.AvailableOnly;
                self.store.state.AvailableOnly = data.isOn;
                self.store.state.FiltersChanged = true;

                var changed = self.store.state.AvailableOnly != oldValue;

                if (self.store.state.ParkSearch.Results.length > 0 && changed) {
                    self.setDisplayParks(false);
                }
            });

            window.SearchResultsAndFiltersEventBus.$on('state-filter-update', function (data) {
                var oldValue = self.store.state.States;
                self.store.state.States = data;
                self.store.state.FiltersChanged = true;

                self.setDisplayParks(false);
            });

            window.SearchResultsAndFiltersEventBus.$on('park-results-updated', function () {
                self.updatePricesFromPms();
            });
        },
        setDisplayParks: function (reloadPrices, parkIdList) {
            var self = this;
            self.loading = true;

            var parkList = self.store.state.ParkSearch.Results;
            var oldDisplayParks = self.store.state.ParkSearch.FilterResults;

            if (parkList.length > 0) {
                //Filter by pet friendly
                if (self.store.state.PetFriendly) {
                    parkList = parkList.filter(function (x) { return x.PetFriendly });
                }

                //Filter by state
                if (self.store.state.States.length > 0) {
                    parkList = parkList.filter(function (x) { return self.store.state.States.indexOf(x.StateCode) >= 0 });
                }

                //Filter by Availability
                if (self.store.state.AvailableOnly) {
                    parkList = parkList.filter(function (x) { return x.IsAvailable });
                }
            }

            self.loading = false;
            self.store.state.ParkSearch.FilterResults = parkList.slice(0, (self.currentPage * self.resultsPerPage));

            self.hasMoreParks = self.store.state.ParkSearch.FilterResults.length < parkList.length;

            if (reloadPrices) {
                if (parkIdList && parkIdList.length > 0) {
                    self.$nextTick(function () {
                        self.updatePricesFromPmsForParkList(parkIdList);
                    });
                } else {
                    self.$nextTick(function () {
                        window.SearchResultsAndFiltersEventBus.$emit("park-results-updated");
                    });
                }
                self.store.state.FiltersChanged = false;
            }

            if (oldDisplayParks === [] || oldDisplayParks.length !== self.store.state.ParkSearch.FilterResults.length) {
                self.initAzureMap();
            }

        },
        getParkSearchRequest: function () {
            var self = this;

            if (window.SearchResultsAndFiltersWidgetStore.state.dateFilterApplied) {
                return {
                    SearchTerm: self.searchTerm,
                    PageNumber: self.currentPage,
                    ResultsPerPage: 500,
                    //PetFriendly: self.store.state.PetFriendly,
                    StartDate: self.store.state.StartDate,
                    EndDate: self.store.state.EndDate,
                    OrderByRating: true,
                    OrderByAvailability: true,
                    //NumAdults: self.store.state.NumAdults,
                    //NumChildren: self.store.state.NumChildren,
                    //NumInfants: self.store.state.NumInfants,
                    //States: self.store.state.States,
                }
            } else {
                return {
                    SearchTerm: self.searchTerm,
                    PageNumber: self.currentPage,
                    ResultsPerPage: 500,
                    OrderByRating: true,
                    OrderByAvailability: true,
                    //PetFriendly: self.store.state.PetFriendly,
                    //StartDate: self.store.state.StartDate,
                    //EndDate: self.store.state.EndDate,
                    //NumAdults: self.store.state.NumAdults,
                    //NumChildren: self.store.state.NumChildren,
                    //NumInfants: self.store.state.NumInfants,
                    //States: self.store.state.States,
                }
            }
        },
        performParkSearch: function () {
            var self = this;
            self.moreParksLoading = true;
            if (!self.loading) {
                self.loading = true;
                var request = this.getParkSearchRequest();
                var url = "/api/Search/ParkSearch";
                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    data: JSON.stringify(request),
                    success: function (response) {
                        response = JSON.parse(response);

                        var newParks = response.Parks.filter(function (x) { return x.Url });
                        self.store.state.ParkSearch.Results = newParks;

                        //self.hasMoreParks = (response.Parks.length >= self.resultsPerPage);
                        self.totalNumResults = response.TotalNumResults;

                        self.moreParksLoading = false;

                        self.setDisplayParks(true);
                    },
                    error: function (xhr, statusText, err) {
                        Common.ShowError("Unexpected error trying to load parks.");
                        self.moreParksLoading = false;
                        self.loading = false;
                    }
                });
            }

        },
        getNextPage: function () {
            var self = this;
            self.currentPage++;
            self.moreParksLoading = true;
            var request = this.getParkSearchRequest();
            var url = "/api/Search/ParkSearchResultsAndFiltersWidgetSearch";
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    response = JSON.parse(response);

                    var newParks = response.Parks.filter(function (x) { return x.Url });
                    self.store.state.ParkSearch.Results = self.store.state.ParkSearch.Results.concat(newParks);

                    self.moreParksLoading = false;

                    self.setDisplayParks(true);
                },
                error: function (xhr, statusText, err) {
                    Common.ShowError("Unexpected error trying to load next page.");
                    self.moreParksLoading = false;
                }
            });
        },
        nextPage: function () {
            var self = this;
            self.currentPage++;
            self.moreParksLoading = true;
            self.store.state.LoadMoreParksClicked = true;

            //Get new park ids
            var parkList = self.store.state.ParkSearch.Results;

            if (parkList.length > 0) {
                //Filter by pet friendly
                if (self.store.state.PetFriendly) {
                    parkList = parkList.filter(function (x) { return x.PetFriendly });
                }

                //Filter by state
                if (self.store.state.States.length > 0) {
                    parkList = parkList.filter(function (x) { return self.store.state.States.indexOf(x.StateCode) >= 0 });
                }

                //Filter by Availability
                if (self.store.state.AvailableOnly) {
                    parkList = parkList.filter(function (x) { return x.IsAvailable });
                }
            }

            parkList = parkList.slice((self.currentPage - 1) * self.resultsPerPage, self.currentPage * self.resultsPerPage);

            var parkIdList = [];
            for (var i = 0; i < parkList.length; i++) {
                parkIdList.push(parkList[i].ParkID);
            }

            self.setDisplayParks(true, parkIdList);
            self.moreParksLoading = false;
        },
        initAzureMap: function () {
            this.parkMap = new AzureMapWithClusteredParkMarkers('searchResultsAndFiltersMapId', this.store.state.ParkSearch.FilterResults);
        },
        initMap: function () {
            //TW: Basic initialisation for google maps
            var uluru = { lat: -25.363, lng: 131.044 };

            window.searchMap = new google.maps.Map(document.getElementById('map'), {
                zoom: 4,
                center: uluru
            });

            window.searchMapInfowindow = new google.maps.InfoWindow({
                content: "",
            });

            if (window.SearchResultsAndFiltersWidgetStore.state.ParkSearch.FilterResults.length > 0 && window.SearchResultsAndFiltersWidgetStore.state.ParkSearch.FilterResults.length != this.markersArray) {
                this.addParks();
            }

            this.clusterMarkers();
        },
        addParks: function () {
            //Takes previously generated map and adds new markers based on search results

            //Clear all markers from the map first
            if (this.markersArray.length > 0) {
                for (var i = 0; i < this.markersArray.length; i++) {
                    this.markersArray[i].setMap(null);
                }
            }

            var parkResults = window.SearchResultsAndFiltersWidgetStore.state.ParkSearch.FilterResults;
            var searchLatLngBounds = new google.maps.LatLngBounds();

            //used for map boundary and zoom
            var googleLatLng = [];

            for (var i = 0; i < parkResults.length; i++) {
                var park = { lat: parkResults[i].Latitude, lng: parkResults[i].Longitude };


                var marker = new google.maps.LatLng(parkResults[i].Latitude, parkResults[i].Longitude);
                googleLatLng.push(marker);

                //TW: Custom map marker icon svg information
                var icon =
                {
                    path: "M16 32c7.6-8.2 11.8-13.5 11.8-20.1s-5.3-11.9-11.8-11.9-11.8 5.3-11.8 11.9 4.1 11.9 11.8 20.1zM16 6.7c2.8 0 5.1 2.3 5.1 5.1s-2.3 5.1-5.1 5.1-5.1-2.3-5.1-5.1 2.3-5.1 5.1-5.1z",
                    fillColor: "#0064b6",
                    fillOpacity: 1.0,
                    anchor: new google.maps.Point(16, 32),
                    strokeWeight: 0,
                    scale: 1
                }

                var marker = new google.maps.Marker({
                    position: park,
                    map: window.searchMap,
                    title: parkResults[i].ParkName,
                    icon: icon,
                    review: parkResults[i].ReviewRating,
                    typeID: parkResults[i].ParkTypeID,
                    image: parkResults[i].Images[0],
                    page: parkResults[i].Url,
                });

                //Put the marker into our markersArray so that we can delete it later if necessary
                this.markersArray.push(marker);

                google.maps.event.addListener(marker, 'click', function () {

                    var imgString = "";
                    var parkBadgeString = "";
                    var reviewString = "";

                    //TW: switch for generating park badge based off of type
                    switch (this.typeID) {
                        case (window.Enums.ParkTypeEnum["Affiliate"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-bullet-rounded c-icon--tertiary-accent"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="227" height="32" viewBox="0 0 227 32"><title>badge-bullet-rounded</title> <path d="M-0.012 3.563c0-4.874 69.747-2.011 98.196-2.011s105.767 2.011 115.202 2.011c9.437 0 29.334 27.599-11.15 27.599-40.483 0-169.104 0.273-185.676 0s-16.572-3.135-16.572-27.599z"></path></svg></span></div> <p class="c-badge__label">Affiliate</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMHoliday"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-3 c-icon--primary"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="136" height="32" viewBox="0 0 136 32"><title>badge-holiday</title> <path d="M0.879 2.702c1.916-4.48 35.716-2.037 42.326-2.037s67.99 0.646 78.154 0.646c10.165 0 31.658 29.085-11.946 29.085-43.605 0-67.97 1.604-90.122 1.604-22.151 0-18.413-12.376-18.413-29.298z"></path></svg></span></div> <p class="c-badge__label">Holiday</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMClassic"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-1 c-icon--callout-variant-two"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="132" height="32" viewBox="0 0 132 32"><title>badge-trapezoid-1</title> <path d="M0.077 0.649c27.028-0.555 38.893 0 68.8 0s56.662 2.811 55.373 2.811c-1.289 0 26.849 26.363-15.713 26.363-42.559 0-72.196 1.774-91.23 1.774s-17.322-4.022-17.231-30.948z"></path></svg></span></div> <p class="c-badge__label">Classic</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMPremier"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-2 c-icon--callout-variant-one"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="135" height="32" viewBox="0 0 135 32"><title>badge-trapezoid-2</title> <path d="M0.031 2.025c17.082-1.098 27.529-1.496 41.797-1.496 14.267 0 67.371-0.268 80.033 4.578 12.665 4.845 27.686 26.365-16.198 26.365h-87.823c-19.403 0-17.809-8.562-17.809-29.448z"></path></svg></span></div> <p class="c-badge__label">Premier</p></span></div>';
                            break;
                        case (window.Enums.ParkTypeEnum["Legacy"]):
                            break;

                    }

                    if (this.image != null && !this.image.MapsImageUrl.includes("placehold")) {
                        imgString = '<img style="width:100%" srcset="' + this.image.MapsImageUrl + ' 300w" sizes="(min-width: 1024px) 20vw,(min-width: 768px) 30vw,30vw" src="' + this.image.MapsImageUrl + '" alt="">'
                    } else {
                        imgString = '<img srcset="https://placehold.it/280x158 280w,https://placehold.it/300x169 300w,https://placehold.it/300x169 300w" sizes="(min-width: 1024px) 20vw,(min-width: 768px) 30vw,30vw" src="https://placehold.it/300x169" alt="">'
                    }

                    if (this.review != null && this.review > 0) {
                        reviewString = '<div class="c-ratings"><span><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns: xlink="http://www.w3.org/1999/xlink" width="30" height="32" viewBox="0 0 30 32" class="svg-defs" style="position: absolute; width: 0px; height: 0px;"><clipPath id="star"><path d="M29.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.3,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6\
                                        c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C0.1,11.5,0,11.2,0,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C14.2,0.2,14.5,0,14.9,0s0.6,0.2,0.9,0.7	l4,8.1l9,1.3C29.4,10.3,29.7,10.5,29.7,11z"></path>\
                                        <path d="M64.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C35.1,11.5,35,11.2,35,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C49.2,0.2,49.5,0,49.9,0	s0.6,0.2,0.9,0.7l4,8.1l9,1.3C64.4,10.3,64.7,10.5,64.7,11z"></path>\
                                        <path d="M99.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C70.1,11.5,70,11.2,70,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C84.2,0.2,84.5,0,84.9,0\
                                        c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C99.4,10.3,99.7,10.5,99.7,11z"></path><path d="M134.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	\
                                        c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C134.4,10.3,134.7,10.5,134.7,11z"></path><path d="M169.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3s-0.2-0.4-0.2-0.6c0-0.1,0-0.2,0-0.4	l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7s0.6,0.2,0.9,0.7l4,8.1l9,1.3	C169.4,10.3,169.7,10.5,169.7,11z"></path></clipPath><clipPath id="star-empty">\
                                        <path d="M29.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.3,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C0.1,11.5,0,11.2,0,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C14.2,0.2,14.5,0,14.9,0s0.6,0.2,0.9,0.7	l4,8.1l9,1.3C29.4,10.3,29.7,10.5,29.7,11z"></path>\
                                        <path d="M64.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C35.1,11.5,35,11.2,35,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C49.2,0.2,49.5,0,49.9,0	s0.6,0.2,0.9,0.7l4,8.1l9,1.3C64.4,10.3,64.7,10.5,64.7,11z"></path>\
                                        <path d="M99.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C70.1,11.5,70,11.2,70,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C84.2,0.2,84.5,0,84.9,0	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C99.4,10.3,99.7,10.5,99.7,11z"></path>\
                                        <path d="M134.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C134.4,10.3,134.7,10.5,134.7,11z"></path>\
                                        <path d="M169.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3s-0.2-0.4-0.2-0.6c0-0.1,0-0.2,0-0.4	l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7s0.6,0.2,0.9,0.7l4,8.1l9,1.3	C169.4,10.3,169.7,10.5,169.7,11z"></path></clipPath><rect id="rating" width="120" height="30" clip-path="url(#star)"></rect></svg>\
                                        <span class="rating-eg"><svg height="12px" viewBox="0 0 170 30" data-rating="1.2" class="rating"><rect x="0" y="0" width="100%" height="100%" clip-path="url(#star-empty)" class="bg-rect" style="fill: rgb(236, 236, 236);"></rect><rect x="0" y="0" width="'+ this.review * 10 + '%" height="100%" clip-path="url(#star)" class="rating-rect" style="fill: rgb(55, 55, 55);"></rect></svg></span></span> <strong class="u-p4">' + Math.round(this.review * 10) / 10 + '/10</strong></div>'
                            ;
                    } else {
                        reviewString = '<strong class="u-p4" style="padding-left: 10px;">No reviews yet</strong>';
                    }


                    //TW: This is the html that will generate the park card structure for the google maps infowindow.
                    //We pass in the above generated strings for images and park badge. We also do calculations for ratings here
                    var contentString = '<div class="infoWindow">\
                         <div class="styleguide-maps" style="background-image: ' + "url('" + +"');" + ' " data-component="location-map-container" data-component-context="Location Pages">\
                         <div class="styleguide-maps__card d-none d-md-block">\
                        <div class="styleguide-maps__card d-none d-md-block"><div data-component="park-card" data-component-context="map" data-component-label="BIG4 Beacon Resort" class="c-card c-card--primary c-card--popup"><div class="c-card__gallery">'
                        + '<a href = "' + this.page + '" class="c-card__img-wrapper"> '
                        + imgString
                        + '</a>'
                        + parkBadgeString
                        + '</div >'
                        + '<div class="c-card__body"> <h3 class="u-h6 c-card__title"><a href="' + this.page + '">'
                        + this.title + '</a ></h3 >'
                        + reviewString
                        + '</div>\
                        </div>\
                       </div>';
                    window.searchMapInfowindow.setContent(contentString);
                    window.searchMapInfowindow.open(window.searchMap, this);
                });

            }

            //TW: Fits the map zoom around the markers by default
            for (var i = 0; i < googleLatLng.length; i++) {
                searchLatLngBounds.extend(googleLatLng[i]);
            }
            window.searchMap.fitBounds(searchLatLngBounds);
        },
        clusterMarkers: function () {
            window.markerCluster = new MarkerClusterer(window.searchMap, this.markersArray, { imagePath: '/Content/Images/GoogleMaps/markerclusterer/images/m' });
        }
    },
    mounted: function () {
        var self = this;
        self.searchTerm = self.term;

        window.SearchResultsAndFiltersEventBus.$on(window.SearchResultsAndFiltersEvents.GET_AVAILABILITY, function (parkAvailabilityRequest) {
            if (self.signalRConnected) {
                self.websiteHub.server.getAvailability(parkAvailabilityRequest);
            }
            //else {
            //    window.SearchEventBus.$once(window.SearchEvents.SIGNALR_CONNECTED, function () {
            //        self.websiteHub.server.getAvailability(parkAvailabilityRequest);
            //    });
            //}
        });

        window.SearchResultsAndFiltersEventBus.$on(window.SearchResultsAndFiltersEvents.SUBSCRIBE_TO_SIGNALR, function (park) {
            self.subscribe(park);
        });

        window.SearchResultsAndFiltersEventBus.$on(window.SearchResultsAndFiltersEvents.UNSUBSCRIBE_FROM_SIGNALR, function (park) {
            self.unsubscribe(park);
        });


        //Set Default Filters
        if (self.editMode) {
            self.performParkSearch();
        } else {
            window.SearchResultsAndFiltersEventBus.$on(window.SearchResultsAndFiltersEvents.SIGNALR_CONNECTED, function () {
                self.performParkSearch();
            });
        }

        self.bindFilterEvents();
        self.loading = false;
    },
    created: function () {
        this.initSignalR();
    }

});;
window.SearchResultsAndFiltersWidgetStore = {
    state: {
        FiltersChanged: false,
        SearchTerm: "",
        StartDate: moment().endOf('day'),
        EndDate: moment().endOf('day').add(1, 'day'),
        PetFriendly: false,
        AvailableOnly: false,
        States: [],
        Latitude: 0,
        Longitude: 0,
        MaxDistanceRange: 0,
        //HolidayType: [],
        //ParkType: [],
        NumAdults: 2,
        NumChildren: 0,
        NumInfants: 0,
        CanUseDistance: false,

        DEFAULT_ADULTS: 1,
        DEFAULT_CHILDREN: 0,
        DEFAULT_INFANTS: 0,
        DEFAULT_START_DATE: moment().endOf('day'),
        DEFAULT_END_DATE: moment().endOf('day').add(1, 'day'),

        ParkSearch: {
            PageNumber: 1,
            ResultsPerPage: 8,
            Results: [],
            FilterResults: [],
            DisplayResults: [],
            MoreParksLoading: false,
            LoadMoreParksClicked: false,
            HasMoreParks: false,
            TotalResults: 0,
            IsHidden: false,
        },
        PanelLoading: true,

    },
    getParkSearchRequest: function () {

        return {
            SearchTerm: this.state.SearchTerm,
            StartDate: this.state.StartDate,
            EndDate: this.state.EndDate,
            PetFriendly: this.state.PetFriendly,
            States: this.state.States,
            Latitude: this.state.Latitude,
            Longitude: this.state.Longitude,
            MaxDistanceRange: this.state.MaxDistanceRange,
            HolidayType: this.state.HolidayType,
            ParkType: this.state.ParkType,
            NumAdults: this.state.NumAdults,
            NumChildren: this.state.NumChildren,
            NumInfants: this.state.NumInfants,
            PageNumber: this.state.ParkSearch.PageNumber,
            ResultsPerPage: this.state.ParkSearch.ResultsPerPage,
        }
    },
    updateDataFromCookie: function () {
        var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
        if (cookie != "") {

            cookie = JSON.parse(cookie);
            if (!!cookie.Dates) {
                this.state.StartDate = moment(cookie.Dates.start);
                this.state.EndDate = moment(cookie.Dates.end);
            }
            if (!!cookie.Guests) {
                this.state.NumAdults = cookie.Guests.adults;
                this.state.NumChildren = cookie.Guests.children;
                this.state.NumInfants = cookie.Guests.infants;
            }

        }
    },
};;
window.SearchEventBus = new Vue();


window.SearchEvents = {
    GET_AVAILABILITY: "get-availability",
    SUBSCRIBE_TO_SIGNALR: "subscribe-to-signalr",
    UNSUBSCRIBE_FROM_SIGNALR: "unsubscribe-from-signalr",
    SIGNALR_CONNECTED: "signalr-connected",

    LOAD_MORE_PARKS: "load-more-parks",
    LOAD_MORE_PARKS_LIST_VIEW: "load-more-parks-list-view",
    LOAD_MORE_DEALS: "load-more-deals",
    LOAD_MORE_ARTICLES: "load-more-articles",
};

;
Vue.component('search-filters', {
    data: function () {
        return {
            store: window.SearchStore.state,
        }
    },
    computed: {
        props: function () {
            return {
                CanUseDistance: this.store.CanUseDistance,
                IsListView: this.store.ListView,
            };
        }
    },

});
;

Vue.component('search-handler', {

    template: "<div style='display:none'></div>",
    data: function () {
        return {
            subscribers: [],
            websiteHub: null,
            signalRConnected: false,
            store: window.SearchStore,
            searchReworkVersion: window.featureFlags.BAPI_3479_search_page_rework,
        }
    },
    methods: {
        setSearchLoading: function () {
            this.store.state.PanelLoading = true;
        },
        setSearchFinishedLoading: function () {
            this.store.state.PanelLoading = false;
        },
        initSignalR: function () {
            var self = this;
            if (this.websiteHub == null) {
                //do the signalr initialisation
                this.websiteHub = $.connection.websiteHub;
                this.websiteHub.client.priceUpdate = this.processSignalRResponse;
                //$.connection.hub.start();

                $.connection.hub.start().done(function () {
                    self.signalRConnected = true;
                    window.SearchEventBus.$emit(window.SearchEvents.SIGNALR_CONNECTED);
                });
            }
        },
        processSignalRResponse: function (data) {
            //get the responses from signal r
            var parkID = 0;
            if (data.AllAccommodations.length > 0) {
                parkID = data.AllAccommodations[0].ParkID;

                //NOTE - THIS IS A TEMPORARY FIX, IDEALLY WE WOULD WANT SOMETHING CLEANER - WM
                //Check the MapViewSignalRPrices list and update a Park's data if we have it, otherwise insert it into the list
                if (this.store.state.ParkSearch.SearchSignalRPrices.length > 0 && this.store.state.ParkSearch.SearchSignalRPrices.filter((x) => { return x.ParkID === parkID }).length > 0) {
                    this.store.state.ParkSearch.SearchSignalRPrices.filter((x) => { return x.ParkID === parkID })[0].AllAccommodations = data.AllAccommodations;
                } else {
                    this.store.state.ParkSearch.SearchSignalRPrices.push({ ParkID: parkID, AllAccommodations: data.AllAccommodations });
                }

                for (var i = 0; i < this.subscribers.length; i++) {
                    if (this.subscribers[i].parkId == parkID) {
                        this.subscribers[i].updatePrice(data);
                    }
                }
            }
        },
        subscribe: function (park) {

            //if the subscriber isn't already subscribed
            if (!_.some(this.subscribers, { ParkID: park.ParkID })) {
                this.subscribers.push(park);
            }
        },
        unsubscribe: function (park) {
            for (var i = 0; i < this.subscribers.length; i++) {
                if (this.subscribers[i].parkID == park.parkID) {
                    this.subscribers.splice(i, 1);
                }
            }
        },
        doSignalR: function () {
            if (this.store.state.FiltersChanged) { return true; }
            else if (this.store.state.DEFAULT_ADULTS != this.store.state.NumAdults) { return true; }
            else if (this.store.state.DEFAULT_CHILDREN != this.store.state.NumChildren) { return true; }
            else if (this.store.state.DEFAULT_INFANTS != this.store.state.NumInfants) { return true; }
            else if (!this.store.state.DEFAULT_START_DATE.isSame(this.store.state.StartDate)) { return true; }
            else if (!this.store.state.DEFAULT_END_DATE.isSame(this.store.state.EndDate)) { return true; }

            return false;
        },
        logGaEvent: function () {
            var defaultView = 'GridViewDefault';
            if (this.searchReworkVersion) {
                defaultView = 'ListViewDefault'
            }


            window.dataLayer = window.dataLayer || [];
            window.dataLayer.push({
                'event': 'SearchExperiment',
                'searchVersion': defaultView,
                'searchTerm': this.store.state.SearchTerm,
                'numberOfResults': this.store.state.ParkSearch.TotalResults
            });
        },
        performParkSearch: function () {
            var self = this;
            
            self.setSearchLoading();
            var request = this.store.getParkSearchRequest();
            request.OrderByAvailability = window.DateFilterStore.state.dateFilterApplied;

            var url = "/api/Search/ParkSearch";
            self.store.state.ParkSearch.ParksLoading = true;
            self.store.state.ParkSearch.Results = [];
            self.store.state.ParkSearch.FilterResults = [];
            self.store.state.ParkSearch.DisplayResults = [];
            $.ajax({
                type: 'POST',
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                data: JSON.stringify(request),
                success: function (response) {
                    self.setSearchFinishedLoading();
                    response = JSON.parse(response);

                    self.store.state.ParkSearch.Results = response.Parks;
                    self.store.state.ParkSearch.MoreParksLoading = false;
                    self.store.state.ParkSearch.TotalResults = response.TotalNumResults;
                    self.store.state.ParkSearch.ParksLoading = false;
                    self.logGaEvent();

                    self.updateFilterResults();
                },
                error: function (xhr, statusText, err) {
                    self.store.state.ParkSearch.ParksLoading = false;
                    self.setSearchFinishedLoading();
                    self.store.state.ParkSearch.MoreParksLoading = false;
                    Common.ShowError("Unexpected error trying to load search results.");
                }
            });

        },
        performDealSearch: function () {
            if (!this.searchReworkVersion) {
                var self = this;
                var request = this.store.getDealSearchRequest();
                var url = "/api/Search/DealSearch";
                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    data: JSON.stringify(request),
                    success: function (response) {
                        self.setSearchFinishedLoading();
                        response = JSON.parse(response);

                        self.store.state.DealSearch.Results = self.store.state.DealSearch.Results.concat(response.Deals);
                        self.store.state.DealSearch.MoreDealsLoading = false;
                        self.store.state.DealSearch.TotalResults = response.TotalNumResults;
                    },
                    error: function (xhr, statusText, err) {
                        self.setSearchFinishedLoading();
                        self.store.state.DealSearch.MoreDealsLoading = false;
                        Common.ShowError("Unexpected error trying to load deals.");
                    }
                });
            }

        },
        performArticleSearch: function () {
            if (!this.searchReworkVersion) {
                var self = this;
                var request = this.store.getArticleSearchRequest();
                var url = "/api/Search/ArticleSearch";
                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    data: JSON.stringify(request),
                    success: function (response) {
                        self.setSearchFinishedLoading();
                        response = JSON.parse(response);

                        self.store.state.ArticleSearch.Results = self.store.state.ArticleSearch.Results.concat(response.Articles);
                        self.store.state.ArticleSearch.MoreArticlesLoading = false;
                        self.store.state.ArticleSearch.TotalResults = response.TotalNumResults;
                    },
                    error: function (xhr, statusText, err) {
                        self.setSearchFinishedLoading();
                        self.store.state.ArticleSearch.MoreArticlesLoading = false;
                        Common.ShowError("Unexpected error trying to load articles.");
                    }
                });
            }

        },
        updatePricesFromPms: function () {
            if (this.doSignalR()) {
                //we want to call SignalR for the parks we have just retrieved.
                var parkAvailabilityRequest =
                {
                    "ArrivalDate": moment(this.store.state.StartDate).format("YYYY-MM-DD"),
                    "DepartingDate": moment(this.store.state.EndDate).format("YYYY-MM-DD"),
                    "NumAdults": this.store.state.NumAdults,
                    "NumKids": this.store.state.NumChildren,
                    ParkIDs: []
                };


                for (var i = 0; i < this.subscribers.length; i++) {
                    this.subscribers[i].setPriceLoading();
                    parkAvailabilityRequest.ParkIDs.push(this.subscribers[i].parkId);
                }

                window.SearchEventBus.$emit(window.SearchEvents.GET_AVAILABILITY, parkAvailabilityRequest);
            }
        },
        updatePricesFromPmsForParkList: function (parkIdList) {
            if (this.doSignalR() && parkIdList.length > 0) {
                //we want to call SignalR for the parks we have just retrieved.
                var parkAvailabilityRequest =
                {
                    "ArrivalDate": moment(this.store.state.StartDate).format("YYYY-MM-DD"),
                    "DepartingDate": moment(this.store.state.EndDate).format("YYYY-MM-DD"),
                    "NumAdults": this.store.state.NumAdults,
                    "NumKids": this.store.state.NumChildren,
                    ParkIDs: []
                };

                for (var i = 0; i < this.subscribers.length; i++) {
                    if (parkIdList.indexOf(this.subscribers[i].parkId) >= 0) {
                        this.subscribers[i].setPriceLoading();
                        parkAvailabilityRequest.ParkIDs.push(this.subscribers[i].parkId);
                    }
                }

                window.SearchEventBus.$emit(window.SearchEvents.GET_AVAILABILITY, parkAvailabilityRequest);
            }
        },
        updateFilterResults: function () {
            var self = this;

            //First set the Filter and Display Results arrays to be empty, also set the page number to be 1 again
            this.store.state.ParkSearch.IsHidden = true;
            this.store.state.ParkSearch.FilterResults = [];
            this.store.state.ParkSearch.DisplayResults = [];
            this.store.state.ParkSearch.PageNumber = 1;

            //Set the Filter Results array to match the search results
            var parkList = this.store.state.ParkSearch.FilterResults.concat(this.store.state.ParkSearch.Results);

            if (this.store.state.PetFriendly) {
                parkList = parkList.filter(function (x) { return x.PetFriendly });
            }

            if (this.store.state.States.length > 0) {
                parkList = parkList.filter(function (x) { return self.store.state.States.indexOf(x.StateCode) >= 0 });
            }

            if (this.store.state.AvailableOnly) {
                parkList = parkList.filter(function (x) { return x.IsAvailable });
            }

            if (this.store.state.CanUseDistance) {
                if (this.store.state.MaxDistanceRange > 0) {
                    parkList = parkList.filter(function (x) { return x.DistanceFromMe <= self.store.state.MaxDistanceRange * 1000 });
                }
            }

            this.store.state.ParkSearch.FilterResults = parkList;

            this.store.state.ParkSearch.HasMoreParks = true;
            var self = this;

            setTimeout(function () {
                self.store.state.ParkSearch.DisplayResults = [];
                self.moveItemsToDisplayArray();
            }, 250);
        },
        moveItemsToDisplayArray: function (parkIdList) {
            var self = this;
            var pageNumber = self.store.state.ParkSearch.PageNumber - 1;
            var numberToTake = self.store.state.ParkSearch.ResultsPerPage;
            var pageThreshold = (pageNumber * numberToTake) + numberToTake;
            var removeLoadMoreButton = false;

            if (self.store.state.ParkSearch.FilterResults.length > 0) {
                if (pageThreshold > self.store.state.ParkSearch.FilterResults.length || pageThreshold == self.store.state.ParkSearch.FilterResults.length) {
                    pageThreshold = self.store.state.ParkSearch.FilterResults.length;
                    removeLoadMoreButton = true;
                }

                for (i = pageNumber * numberToTake; i < pageThreshold; i++) {

                    self.store.state.ParkSearch.DisplayResults = self.store.state.ParkSearch.DisplayResults.concat(self.store.state.ParkSearch.FilterResults[i]);
                }

                if (removeLoadMoreButton) {
                    self.store.state.ParkSearch.MoreParksLoading = false;
                    self.store.state.ParkSearch.HasMoreParks = false;
                }

                self.store.state.ParkSearch.PageNumber += 1;

                setTimeout(function () { self.store.state.ParkSearch.IsHidden = false }, 250);
            }

            if (window.DateFilterStore.state.dateFilterApplied) {
                if (parkIdList && parkIdList.length > 0) {
                    self.$nextTick(function () {
                        self.updatePricesFromPmsForParkList(parkIdList);
                    });
                } else {
                    self.$nextTick(function () {
                        //window.SearchEventBus.$emit("park-results-updated");
                        self.updatePricesFromPms();
                    });
                }
            } else if (self.store.state.NumAdults != 2 || self.store.state.NumChildren != 0 || self.store.state.NumInfants != 0) {
                if (parkIdList && parkIdList.length > 0) {
                    self.$nextTick(function () {
                        self.updatePricesFromPmsForParkList(parkIdList);
                    });
                } else {
                    self.$nextTick(function () {
                        window.SearchEventBus.$emit("park-results-updated");
                    });
                }
            }

        },
        bindFilterEvents: function () {
            var self = this;

            window.SearchEventBus.$on('date-filter-update', function (data) {
                /*Check for date filter cookie*/
                try {
                    var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                    if (cookie != "") {

                        cookie = JSON.parse(cookie);
                        if (!!cookie.Dates) {
                            window.DateFilterStore.state.dateFilterApplied = true;
                        }
                        else {
                            window.DateFilterStore.state.dateFilterApplied = false;
                        }
                    }
                    else {
                        window.DateFilterStore.state.dateFilterApplied = false;
                    }
                }
                catch (e) {
                }

                if (window.DateFilterStore.state.dateFilterApplied == true && (self.store.state.StartDate !== data.start || self.store.state.EndDate !== data.end)) {
                    self.store.state.StartDate = data.start;
                    self.store.state.EndDate = data.end;
                    self.store.state.FiltersChanged = true;

                    //Reload the search results with the new dates
                    self.performParkSearch();

                } else {
                    self.store.state.StartDate = self.store.state.DEFAULT_START_DATE;
                    self.store.state.EndDate = self.store.state.DEFAULT_END_DATE;
                    self.store.state.FiltersChanged = true;
                    //self.updatePricesFromPms();
                }

            });

            window.SearchEventBus.$on('guest-filter-update', function (data) {
                var oldValue = {adults: self.store.state.NumAdults, children: self.store.state.NumChildren, infants: self.store.state.NumInfants};
                self.store.state.NumAdults = data.adults;
                self.store.state.NumChildren = data.children;
                self.store.state.NumInfants = data.infants;
                self.store.state.FiltersChanged = true;
                var newValue = { adults: self.store.state.NumAdults, children: self.store.state.NumChildren, infants: self.store.state.NumInfants };

                var changed = newValue.adults != oldValue.adults || newValue.children != oldValue.children || newValue.infants != oldValue.infants;
                
                if (self.subscribers.length === 0 && changed) {
                    window.SearchEventBus.$once("park-results-updated", function () {
                        //we need to postpone this for the initial load, so it doesn't happen until the parks are all subscribed                
                        self.updatePricesFromPms();
                    });
                }
                else if (changed) {
                    self.updatePricesFromPms();
                }

                self.updateFilterPersonaScore();
            });

            window.SearchEventBus.$on('pets-filter-update', function (data) {
                var oldValue = self.store.state.PetFriendly;
                self.store.state.PetFriendly = data.isOn;
                self.store.state.FiltersChanged = true;

                var changed = self.store.state.PetFriendly != oldValue;

                if (self.store.state.ParkSearch.Results.length > 0 && changed) {
                    self.updateFilterResults();
                }

                //self.updatePricesFromPms();
            });

            window.SearchEventBus.$on('availability-filter-update', function (data) {
                var oldValue = self.store.state.AvailableOnly;
                self.store.state.AvailableOnly = data.isOn;
                self.store.state.FiltersChanged = true;

                var changed = self.store.state.AvailableOnly != oldValue;

                if (self.store.state.ParkSearch.Results.length > 0 && changed) {
                    self.updateFilterResults();
                }

                //self.updatePricesFromPms();
            });

            window.SearchEventBus.$on('state-filter-update', function (data) {
                var oldValue = self.store.state.States;
                self.store.state.States = data;
                self.store.state.FiltersChanged = true;

                var changed = (self.store.state.States.length == oldValue.length) && self.store.state.States.every(function (element, index) {
                    return element === oldValue[index];
                });

                if (!changed && self.store.state.States.length != oldValue.length) {
                    changed = true;
                } else if (changed && self.store.state.States.length == 0 && oldValue.length == 0)
                {
                    changed = false;
                }

                if (self.store.state.ParkSearch.Results.length > 0 && changed) {
                    self.updateFilterResults();
                }

                //self.updatePricesFromPms();
            });

            window.SearchEventBus.$on('distance-filter-update', function (data) {
                var oldValue = self.store.state.MaxDistanceRange;
                self.store.state.MaxDistanceRange = data.distance;
                self.store.state.FiltersChanged = true;

                var changed = self.store.state.MaxDistanceRange != oldValue;

                if (self.store.state.ParkSearch.Results.length > 0 && changed) {
                    self.updateFilterResults();
                }

                //self.updatePricesFromPms();
            });

            window.SearchEventBus.$on(window.SearchEvents.LOAD_MORE_PARKS, function () {
                //var self = this;
                self.store.state.ParkSearch.MoreParksLoading = true;
                self.store.state.LoadMoreParksClicked = true;

                if (window.DateFilterStore.state.dateFilterApplied || (self.store.state.NumAdults != 2 || self.store.state.NumChildren != 0 || self.store.state.NumInfants != 0)) {
                    //Get new park ids
                    var parkList = self.store.state.ParkSearch.Results;

                    if (parkList.length > 0) {
                        //Filter by pet friendly
                        if (self.store.state.PetFriendly) {
                            parkList = parkList.filter(function (x) { return x.PetFriendly });
                        }

                        //Filter by state
                        if (self.store.state.States.length > 0) {
                            parkList = parkList.filter(function (x) { return self.store.state.States.indexOf(x.StateCode) >= 0 });
                        }

                        //Filter by Availability
                        if (self.store.state.AvailableOnly) {
                            parkList = parkList.filter(function (x) { return x.IsAvailable });
                        }
                    }

                    parkList = parkList.slice((self.store.state.ParkSearch.PageNumber - 1) * self.store.state.ParkSearch.ResultsPerPage, self.store.state.ParkSearch.PageNumber * self.store.state.ParkSearch.ResultsPerPage);

                    var parkIdList = [];
                    for (var i = 0; i < parkList.length; i++) {
                        parkIdList.push(parkList[i].ParkID);
                    }

                    self.moveItemsToDisplayArray(parkIdList);
                } else {
                    self.moveItemsToDisplayArray();
                }

                self.store.state.ParkSearch.MoreParksLoading = false;
            });

            window.SearchEventBus.$on(window.SearchEvents.LOAD_MORE_PARKS_LIST_VIEW, function (parkIdList) {
                self.updatePricesFromPmsForParkList(parkIdList);
            });

            window.SearchEventBus.$on(window.SearchEvents.LOAD_MORE_DEALS, function () {
                self.store.state.DealSearch.MoreDealsLoading = true;
                self.store.state.DealSearch.PageNumber += 1;
                //self.performDealSearch();
            });

            window.SearchEventBus.$on(window.SearchEvents.LOAD_MORE_ARTICLES, function () {
                self.store.state.ArticleSearch.MoreArticlesLoading = true;
                self.store.state.ArticleSearch.PageNumber += 1;
                self.performArticleSearch();
            });
        },
        updateFilterPersonaScore: function () {
            var self = this;
            var url = "";

            /*Post activity for personalisation*/
            if (self.store.state.NumAdults > 2) {
                url += "/api/Personalization/FilteredByGroup";
            }
            else if (self.store.state.NumChildren >= 1 || self.store.state.NumInfants) {
                url += "/api/Personalization/FilteredByFamily";
            }
            else if (self.store.state.NumAdults == 2 && self.store.state.NumChildren == 0 && self.store.state.NumInfants == 0) {
                url += "/api/Personalization/FilteredByNomad";
            }

            if (url != "") {
                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    success: function () {
                    },
                    error: function (xhr, ajaxOptions, thrownError) {

                    }

                });
            }
        },
    },
    computed: {
        parks: function () {
            return this.store.state.ParkSearch.Results;
        },
        filterparks: function () {
            return this.store.state.ParkSearch.FilterResults;
        },
        deals: function () {
            return this.store.state.DealSearch.Results;
        },
        articles: function () {
            return this.store.state.ArticleSearch.Results;
        },

    },
    mounted: function () {

        var self = this;

        window.SearchEventBus.$on(window.SearchEvents.GET_AVAILABILITY, function (parkAvailabilityRequest) {
            if (self.signalRConnected) {
                self.websiteHub.server.getAvailability(parkAvailabilityRequest);
            }
            //else {
            //    window.SearchEventBus.$once(window.SearchEvents.SIGNALR_CONNECTED, function () {
            //        self.websiteHub.server.getAvailability(parkAvailabilityRequest);
            //    });
            //}
        });

        window.SearchEventBus.$on(window.SearchEvents.SUBSCRIBE_TO_SIGNALR, function (park) {
            self.subscribe(park);
        });

        window.SearchEventBus.$on(window.SearchEvents.UNSUBSCRIBE_FROM_SIGNALR, function (park) {
            self.unsubscribe(park);
        });


        window.SearchEventBus.$on(window.SearchEvents.SIGNALR_CONNECTED, function () {
            self.setSearchLoading();
            self.performParkSearch();
            self.performDealSearch();
            self.performArticleSearch();
        });

        this.bindFilterEvents();
        
        this.store.state.SearchTerm = this.URIDecode(Common.GetUrlParameter("search"));

 
        

    },
    created: function () {
        this.store.updateDataFromCookie();


        this.initSignalR();
        var self = this;

        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (position) {
                //if this works, then we can use the distance filter
                self.store.state.CanUseDistance = true;
                self.store.state.Latitude = position.coords.latitude;
                self.store.state.Longitude = position.coords.longitude;
            });
        }
    }
});
;
Vue.component("search-map", {
    template: "#SEARCH_MAP_TEMPLATE",
    props: ["parks"],
    data: function () {
        return {
            mapId: _.uniqueId('searchMapId'),
            markersArray: [],
        }
    },
    methods:
    {
        init: function () {
            new AzureMapWithClusteredParkMarkers('searchMapId', this.parks);
        },
        addParks: function ()
        {
            //Takes previously generated map and adds new markers based on search results

            //Clear all markers from the map first
            if (this.markersArray.length > 0) {
                for (var i = 0; i < this.markersArray.length; i++) {
                    this.markersArray[i].setMap(null);
                }
            }

            var parkResults = window.SearchStore.state.ParkSearch.FilterResults;
            var searchLatLngBounds = new google.maps.LatLngBounds();

            //used for map boundary and zoom
            var googleLatLng = [];

            for (var i = 0; i < parkResults.length; i++) {
                var park = { lat: parkResults[i].Latitude, lng: parkResults[i].Longitude };


                var marker = new google.maps.LatLng(parkResults[i].Latitude, parkResults[i].Longitude);
                googleLatLng.push(marker);

                //TW: Custom map marker icon svg information
                var icon =
                {
                    path: "M16 32c7.6-8.2 11.8-13.5 11.8-20.1s-5.3-11.9-11.8-11.9-11.8 5.3-11.8 11.9 4.1 11.9 11.8 20.1zM16 6.7c2.8 0 5.1 2.3 5.1 5.1s-2.3 5.1-5.1 5.1-5.1-2.3-5.1-5.1 2.3-5.1 5.1-5.1z",
                    fillColor: "#0064b6",
                    fillOpacity: 1.0,
                    anchor: new google.maps.Point(16, 32),
                    strokeWeight: 0,
                    scale: 1
                }

                var marker = new google.maps.Marker({
                    position: park,
                    map: window.searchMap,
                    title: parkResults[i].ParkName,
                    icon: icon,
                    review: parkResults[i].ReviewRating,
                    typeID: parkResults[i].ParkTypeID,
                    image: parkResults[i].Images[0],
                    page: parkResults[i].Url,
                });

                //Put the marker into our markersArray so that we can delete it later if necessary
                this.markersArray.push(marker);

                google.maps.event.addListener(marker, 'click', function () {

                    var imgString = "";
                    var parkBadgeString = "";
                    var reviewString = "";

                    //TW: switch for generating park badge based off of type
                    switch (this.typeID) {
                        case (window.Enums.ParkTypeEnum["Affiliate"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-bullet-rounded c-icon--tertiary-accent"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="227" height="32" viewBox="0 0 227 32"><title>badge-bullet-rounded</title> <path d="M-0.012 3.563c0-4.874 69.747-2.011 98.196-2.011s105.767 2.011 115.202 2.011c9.437 0 29.334 27.599-11.15 27.599-40.483 0-169.104 0.273-185.676 0s-16.572-3.135-16.572-27.599z"></path></svg></span></div> <p class="c-badge__label">Affiliate</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMHoliday"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-3 c-icon--primary"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="136" height="32" viewBox="0 0 136 32"><title>badge-holiday</title> <path d="M0.879 2.702c1.916-4.48 35.716-2.037 42.326-2.037s67.99 0.646 78.154 0.646c10.165 0 31.658 29.085-11.946 29.085-43.605 0-67.97 1.604-90.122 1.604-22.151 0-18.413-12.376-18.413-29.298z"></path></svg></span></div> <p class="c-badge__label">Holiday</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMClassic"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-1 c-icon--callout-variant-two"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="132" height="32" viewBox="0 0 132 32"><title>badge-trapezoid-1</title> <path d="M0.077 0.649c27.028-0.555 38.893 0 68.8 0s56.662 2.811 55.373 2.811c-1.289 0 26.849 26.363-15.713 26.363-42.559 0-72.196 1.774-91.23 1.774s-17.322-4.022-17.231-30.948z"></path></svg></span></div> <p class="c-badge__label">Classic</p></span></div>'
                            break;
                        case (window.Enums.ParkTypeEnum["FCOMPremier"]):
                            parkBadgeString = '<div class="c-card__badge"><span data-component="badge" class="c-badge u-p5 c-badge--secondary"><div class="c-badge__bg"><span class="c-icon badge-trapezoid-2 c-icon--callout-variant-one"><svg preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg" width="135" height="32" viewBox="0 0 135 32"><title>badge-trapezoid-2</title> <path d="M0.031 2.025c17.082-1.098 27.529-1.496 41.797-1.496 14.267 0 67.371-0.268 80.033 4.578 12.665 4.845 27.686 26.365-16.198 26.365h-87.823c-19.403 0-17.809-8.562-17.809-29.448z"></path></svg></span></div> <p class="c-badge__label">Premier</p></span></div>';
                            break;
                        case (window.Enums.ParkTypeEnum["Legacy"]):
                            break;

                    }

                    if (this.image != null && !this.image.MapsImageUrl.includes("placehold")) {
                        imgString = '<img style="width:100%" srcset="' + this.image.MapsImageUrl + ' 300w" sizes="(min-width: 1024px) 20vw,(min-width: 768px) 30vw,30vw" src="' + this.image.MapsImageUrl + '" alt="">'
                    } else {
                        imgString = '<img srcset="https://placehold.it/280x158 280w,https://placehold.it/300x169 300w,https://placehold.it/300x169 300w" sizes="(min-width: 1024px) 20vw,(min-width: 768px) 30vw,30vw" src="https://placehold.it/300x169" alt="">'
                    }

                    if (this.review != null && this.review > 0) {
                        reviewString = '<div class="c-ratings"><span><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns: xlink="http://www.w3.org/1999/xlink" width="30" height="32" viewBox="0 0 30 32" class="svg-defs" style="position: absolute; width: 0px; height: 0px;"><clipPath id="star"><path d="M29.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.3,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6\
                                        c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C0.1,11.5,0,11.2,0,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C14.2,0.2,14.5,0,14.9,0s0.6,0.2,0.9,0.7	l4,8.1l9,1.3C29.4,10.3,29.7,10.5,29.7,11z"></path>\
                                        <path d="M64.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C35.1,11.5,35,11.2,35,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C49.2,0.2,49.5,0,49.9,0	s0.6,0.2,0.9,0.7l4,8.1l9,1.3C64.4,10.3,64.7,10.5,64.7,11z"></path>\
                                        <path d="M99.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C70.1,11.5,70,11.2,70,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C84.2,0.2,84.5,0,84.9,0\
                                        c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C99.4,10.3,99.7,10.5,99.7,11z"></path><path d="M134.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	\
                                        c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C134.4,10.3,134.7,10.5,134.7,11z"></path><path d="M169.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	\
                                        c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3s-0.2-0.4-0.2-0.6c0-0.1,0-0.2,0-0.4	l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7s0.6,0.2,0.9,0.7l4,8.1l9,1.3	C169.4,10.3,169.7,10.5,169.7,11z"></path></clipPath><clipPath id="star-empty">\
                                        <path d="M29.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.3,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C0.1,11.5,0,11.2,0,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C14.2,0.2,14.5,0,14.9,0s0.6,0.2,0.9,0.7	l4,8.1l9,1.3C29.4,10.3,29.7,10.5,29.7,11z"></path>\
                                        <path d="M64.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C35.1,11.5,35,11.2,35,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C49.2,0.2,49.5,0,49.9,0	s0.6,0.2,0.9,0.7l4,8.1l9,1.3C64.4,10.3,64.7,10.5,64.7,11z"></path>\
                                        <path d="M99.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6c-0.1,0.2-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3C70.1,11.5,70,11.2,70,11c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1C84.2,0.2,84.5,0,84.9,0	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C99.4,10.3,99.7,10.5,99.7,11z"></path>\
                                        <path d="M134.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3c-0.1-0.2-0.2-0.4-0.2-0.6	c0-0.1,0-0.2,0-0.4l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7	c0.4,0,0.6,0.2,0.9,0.7l4,8.1l9,1.3C134.4,10.3,134.7,10.5,134.7,11z"></path>\
                                        <path d="M169.7,11c0,0.3-0.2,0.5-0.5,0.9l-6.5,6.3l1.5,8.9c0,0.1,0,0.2,0,0.4c0,0.2-0.1,0.5-0.2,0.6s-0.3,0.3-0.5,0.3	c-0.2,0-0.5-0.1-0.7-0.2l-8-4.2l-8,4.2c-0.3,0.1-0.5,0.2-0.7,0.2c-0.2,0-0.4-0.1-0.6-0.3s-0.2-0.4-0.2-0.6c0-0.1,0-0.2,0-0.4	l1.5-8.9l-6.5-6.3c-0.3-0.3-0.4-0.6-0.4-0.9c0-0.4,0.3-0.7,1-0.8l9-1.3l4-8.1c0.2-0.5,0.5-0.7,0.9-0.7s0.6,0.2,0.9,0.7l4,8.1l9,1.3	C169.4,10.3,169.7,10.5,169.7,11z"></path></clipPath><rect id="rating" width="120" height="30" clip-path="url(#star)"></rect></svg>\
                                        <span class="rating-eg"><svg height="12px" viewBox="0 0 170 30" data-rating="1.2" class="rating"><rect x="0" y="0" width="100%" height="100%" clip-path="url(#star-empty)" class="bg-rect" style="fill: rgb(236, 236, 236);"></rect><rect x="0" y="0" width="'+ this.review * 10 + '%" height="100%" clip-path="url(#star)" class="rating-rect" style="fill: rgb(55, 55, 55);"></rect></svg></span></span> <strong class="u-p4">' + Math.round(this.review * 10) / 10 + '/10</strong></div>'
                            ;
                    } else {
                        reviewString = '<strong class="u-p4" style="padding-left: 10px;">No reviews yet</strong>';
                    }


                    //TW: This is the html that will generate the park card structure for the google maps infowindow.
                    //We pass in the above generated strings for images and park badge. We also do calculations for ratings here
                    var contentString = '<div class="infoWindow">\
                         <div class="styleguide-maps" style="background-image: ' + "url('" + +"');" + ' " data-component="location-map-container" data-component-context="Location Pages">\
                         <div class="styleguide-maps__card d-none d-md-block">\
                        <div class="styleguide-maps__card d-none d-md-block"><div data-component="park-card" data-component-context="map" data-component-label="BIG4 Beacon Resort" class="c-card c-card--primary c-card--popup"><div class="c-card__gallery">'
                        + '<a href = "' + this.page + '" class="c-card__img-wrapper"> '
                        + imgString
                        + '</a>'
                        + parkBadgeString
                        + '</div >'
                        + '<div class="c-card__body"> <h3 class="u-h6 c-card__title"><a href="' + this.page + '">'
                        + this.title + '</a ></h3 >'
                        + reviewString
                        + '</div>\
                        </div>\
                       </div>';
                    window.searchMapInfowindow.setContent(contentString);
                    window.searchMapInfowindow.open(window.searchMap, this);
                });
               
            }

            //TW: Fits the map zoom around the markers by default
            for (var i = 0; i < googleLatLng.length; i++)
            {
                searchLatLngBounds.extend(googleLatLng[i]);
            }
            window.searchMap.fitBounds(searchLatLngBounds);
        },
        clusterMarkers: function ()
        {
            window.markerCluster = new MarkerClusterer(window.searchMap, this.markersArray, { imagePath: '/Content/Images/GoogleMaps/markerclusterer/images/m' });
        }
    },
    mounted: function ()
    {
        this.init();
    },
});;
Vue.component('search-map-button', {
    props: [],
    template: '#SearchMapButtonTemplate',

    data: function () {
        return {
            state: {
                searchState: window.SearchStore.state,
                listViewMap: window.featureFlags.BAPI_3717_search_list_view_map,
            },
        };
    },
    methods: {

        viewMap: function () {

            if (this.state.listViewMap) {
                if (this.state.searchState.SearchViewMode === 'List') {
                    this.state.searchState.ShowListViewMap = true;
                } else {
                    this.$nextTick(() => {
                        var element = document.getElementById("mapScrollDiv");
                        //if the map has been loaded by scrolling or not
                        var mapIsLoaded = document.getElementById("map") != null;

                        if (!mapIsLoaded) {
                            element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                        } else {
                            element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                        }
                    });
                }

            } else {
                if (this.state.searchState.SearchViewMode === 'List') {
                    this.state.searchState.SearchViewMode = 'Grid';
                }

                this.$nextTick(() => {
                    var element = document.getElementById("mapScrollDiv");
                    //if the map has been loaded by scrolling or not
                    var mapIsLoaded = document.getElementById("map") != null;

                    if (!mapIsLoaded) {
                        element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    } else {
                        element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    }
                });
            }
        }
    },
    created: function () {

  
    }

});;
Vue.component('search-results-panel', {
    data: function () {
        return {
            store: window.SearchStore.state,
            searchReworkVersion: window.featureFlags.BAPI_3479_search_page_rework,
            listViewMap: window.featureFlags.BAPI_3717_search_list_view_map,
            showPlaceholderLoading: window.featureFlags.BAPI_3734_search_placeholder_loading,
            listViewParksToShow: 5,
        }
    },
    computed: {
        parks: function () {
            return this.store.ParkSearch.DisplayResults;
        },
        parkResults: function () {
            return this.store.ParkSearch.Results;
        },
        listViewParks: function () {
            return this.store.ParkSearch.FilterResults.slice(0, this.listViewParksToShow);
        },
        listViewHasMoreParks: function () {
            return this.listViewParksToShow < this.store.ParkSearch.FilterResults.length;
        },
        isHidden: function () {
            return this.store.ParkSearch.IsHidden;
        },
        deals: function () {
            return this.store.DealSearch.Results;
        },
        articles: function () {
            return this.store.ArticleSearch.Results;
        },
        searchString: function () {
            return this.store.SearchTerm;
        },
        parkPanelLoading: function () {
            return this.store.ParkSearch.ParksLoading;
        },
        parksLoading: function () {
            return this.store.ParkSearch.MoreParksLoading;
        },
        dealsLoading: function () {
            return this.store.DealSearch.MoreDealsLoading;
        },
        articlesLoading: function () {
            return this.store.ArticleSearch.MoreArticlesLoading;
        },
        panelLoading: function () {
            return this.store.PanelLoading;
        },
        totalResults: function () {
            //WM 19/01/2021 - Changed to only show number of park results (as requested by BIG4)

            //return this.store.ParkSearch.TotalResults + this.store.DealSearch.TotalResults + this.store.ArticleSearch.TotalResults;
            return this.store.ParkSearch.TotalResults;
        },
        hasMoreParks: function () {
            return this.store.ParkSearch.HasMoreParks;
        },
        hasMoreDeals: function () {
            return this.store.DealSearch.TotalResults != this.deals.length;
        },
        hasMoreArticles: function () {
            return this.store.ArticleSearch.TotalResults != this.articles.length;
        },
        searchViewMode: function () {
            return this.store.SearchViewMode;
        },
        showListViewMap: function () {
            return this.store.ShowListViewMap;
        },
    },
    methods:{

        loadMoreParks: function () {
            //this.$refs.searchMap.init();
            window.SearchEventBus.$emit(window.SearchEvents.LOAD_MORE_PARKS);
        },
        loadMoreDeals: function () {
            window.SearchEventBus.$emit(window.SearchEvents.LOAD_MORE_DEALS);
        },
        loadMoreArticles: function () {
            window.SearchEventBus.$emit(window.SearchEvents.LOAD_MORE_ARTICLES);
        },
        listViewLoadMoreParks: function () {
            var self = this;

            // Get new parks in list view
            var newListViewParks = this.store.ParkSearch.FilterResults.slice(this.listViewParksToShow, this.listViewParksToShow + 5);
            var parkIdList = [];

            this.listViewParksToShow += 5;

            for (var i = 0; i < newListViewParks.length; i++) {
                parkIdList.push(newListViewParks[i].ParkID);
            }

            if (window.DateFilterStore.state.dateFilterApplied) {
                if (parkIdList && parkIdList.length > 0) {
                    self.$nextTick(function () {
                        window.SearchEventBus.$emit(window.SearchEvents.LOAD_MORE_PARKS_LIST_VIEW, parkIdList);
                    });
                } else {
                    self.$nextTick(function () {
                        //window.SearchEventBus.$emit("park-results-updated");
                        window.SearchEventBus.$emit("park-results-updated");
                    });
                }
            } else if (self.store.state.NumAdults != 2 || self.store.state.NumChildren != 0 || self.store.state.NumInfants != 0) {
                if (parkIdList && parkIdList.length > 0) {
                    self.$nextTick(function () {
                        window.SearchEventBus.$emit(window.SearchEvents.LOAD_MORE_PARKS_LIST_VIEW, parkIdList);
                    });
                } else {
                    self.$nextTick(function () {
                        window.SearchEventBus.$emit("park-results-updated");
                    });
                }
            }
        },
        alert: function () {
            alert('123');
        }
    },
});
;
window.SearchStore = {
    state: {
        FiltersChanged:false,
        SearchTerm: "",
        StartDate: moment().endOf('day'),
        EndDate: moment().endOf('day').add(1,'day'),
        PetFriendly: false,
        AvailableOnly: false,
        States: [],
        Latitude: 0,
        Longitude: 0,
        MaxDistanceRange: 0,
        //HolidayType: [],
        //ParkType: [],
        NumAdults: 1,
        NumChildren: 0,
        NumInfants: 0,
        CanUseDistance:false,

        DEFAULT_ADULTS: 1,
        DEFAULT_CHILDREN: 0,
        DEFAULT_INFANTS: 0,
        DEFAULT_START_DATE: moment().endOf('day'),
        DEFAULT_END_DATE: moment().endOf('day').add(1, 'day'),
        ListView: window.featureFlags.BAPI_3479_search_page_rework,
        SearchViewMode: 'List',
        ShowListViewMap: false,

        ParkSearch: {
            PageNumber: 1,
            ResultsPerPage: 8,
            Results: [],
            FilterResults: [],
            DisplayResults: [],
            MoreParksLoading: false,
            LoadMoreParksClicked: false,
            HasMoreParks: false,
            TotalResults: 0,
            IsHidden: false,
            ParksLoading: true,
            OrderByRating: false,
            OrderByAvailability: false,
            SearchSignalRPrices: [],
        },
        DealSearch: {
            PageNumber: 1,
            ResultsPerPage: 8,
            Results: [],
            MoreDealsLoading: false,
            HasMoreDeals: false,
            TotalResults: 0,
        },
        ArticleSearch: {
            PageNumber: 1,
            ResultsPerPage: 8,
            Results: [],
            MoreArticlesLoading: false,
            HasMoreArticles: false,
            TotalResults: 0,
        },
        PanelLoading: true,

    },
    getParkSearchRequest: function () {

        if (this.state.StartDate != this.state.DEFAULT_START_DATE && this.state.EndDate != this.state.DEFAULT_END_DATE) {
            return {
                SearchTerm: this.state.SearchTerm,
                StartDate: this.state.StartDate,
                EndDate: this.state.EndDate,
                PetFriendly: this.state.PetFriendly,
                States: this.state.States,
                Latitude: this.state.Latitude,
                Longitude: this.state.Longitude,
                MaxDistanceRange: this.state.MaxDistanceRange,
                HolidayType: this.state.HolidayType,
                ParkType: this.state.ParkType,
                NumAdults: this.state.NumAdults,
                NumChildren: this.state.NumChildren,
                NumInfants: this.state.NumInfants,
                //PageNumber: this.state.ParkSearch.PageNumber,
                PageNumber: 1,
                //ResultsPerPage: this.state.ParkSearch.ResultsPerPage,
                ResultsPerPage: 24
            }
        } else {
            return {
                SearchTerm: this.state.SearchTerm,
                //StartDate: this.state.StartDate,
                //EndDate: this.state.EndDate,
                PetFriendly: this.state.PetFriendly,
                States: this.state.States,
                Latitude: this.state.Latitude,
                Longitude: this.state.Longitude,
                MaxDistanceRange: this.state.MaxDistanceRange,
                HolidayType: this.state.HolidayType,
                ParkType: this.state.ParkType,
                NumAdults: this.state.NumAdults,
                NumChildren: this.state.NumChildren,
                NumInfants: this.state.NumInfants,
                //PageNumber: this.state.ParkSearch.PageNumber,
                PageNumber: 1,
                //ResultsPerPage: this.state.ParkSearch.ResultsPerPage,
                ResultsPerPage: 24
            }
        }

    },
    getDealSearchRequest: function () {

        return {
            SearchTerm: this.state.SearchTerm,
            StartDate: this.state.StartDate,
            EndDate: this.state.EndDate,
            PetFriendly: this.state.PetFriendly,
            States: this.state.States,
            Latitude: this.state.Latitude,
            Longitude: this.state.Longitude,
            MaxDistanceRange: this.state.MaxDistanceRange,
            HolidayType: this.state.HolidayType,
            ParkType: this.state.ParkType,
            NumAdults: this.state.NumAdults,
            NumChildren: this.state.NumChildren,
            NumInfants: this.state.NumInfants,
            PageNumber: this.state.DealSearch.PageNumber,
            ResultsPerPage: this.state.DealSearch.ResultsPerPage,
        }
    },
    getArticleSearchRequest: function () {

        return {
            SearchTerm: this.state.SearchTerm,
            Latitude: this.state.Latitude,
            Longitude: this.state.Longitude,
            MaxDistanceRange: this.state.MaxDistanceRange,
            PageNumber: this.state.ArticleSearch.PageNumber,
            ResultsPerPage: this.state.ArticleSearch.ResultsPerPage,
        }
    },
    updateDataFromCookie: function () {
        var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
        if (cookie != "") {

            cookie = JSON.parse(cookie);
            if (!!cookie.Dates) {
                this.state.StartDate = moment(cookie.Dates.start);
                this.state.EndDate = moment(cookie.Dates.end);
            }
            if (!!cookie.Guests) {
                this.state.NumAdults = cookie.Guests.adults;
                this.state.NumChildren = cookie.Guests.children;
                this.state.NumInfants = cookie.Guests.infants;
            }

        }
    },
};;
Vue.use(AsyncComputed);

Vue.component('search-data-wrapper', {
    mixins:[MIXIN_SEARCH_SAVED_SEARCHES],
    props: {
        account: {
            type: Object,
            default: {},
        },
        scrolled:
        {
            default: false,
        },
        homeBanner:
        {
            default:false,
        },
        defaultResults: {
            type: Array,
            default: function () { return [] },
        },
    },
    data: function () {
        return {
            searchString: '',
            error: '',
            request: [],
            recentlyViewed: [],
        };
    },
    computed: {
        //data() {
        //    if (this.hasRecentlyViewed) {
        //        return this.recentlyViewed;
        //    }
        //    return [{ title: "Result1" }, { title: "Result2" }, { title: "Result3" }];

        //},
        hasRecentlyViewed: function () {
            return this.recentlyViewed.length > 0 && this.searchString.length == 0;
        },
        props: function () {
            return {
                RecentlyViewed: this.recentlyViewed,
                HasRecentlyViewed: this.hasRecentlyViewed,
                GoToUrl: this.GoToUrl,
                IsScrolled: this.scrolled,
                IsHomeBanner: this.homeBanner,
                CloseKeyBoard: this.closeKeyBoard,
            }
        }
    },
    asyncComputed: {
        data: {
            get:function() {
                const partnerParkTypeID = window.Enums.ParkTypeEnum['Affiliate'];
                var results = [];

                if (this.searchString.length > 0) {

                    return axios.get('/api/Search/SiteSearch', {
                        params: {
                            SearchTerm: this.searchString
                        }
                    }).then(function (response) {
                        response = JSON.parse(response.data);

                        var resultParks = response.Parks;
                        var resultDeals = response.Deals;
                        var resultArticles = response.Articles;
                        var resultRegions = response.Regions;
                        
                        for (var i = 0; i < resultParks.length; i++) {
                            results.push({
                                "icon": resultParks[i].ParkTypeID === partnerParkTypeID ? 'handshake' : "big4",
                                "url": resultParks[i].Url,
                                "title": resultParks[i].ParkName,
                                "location": resultParks[i].Location,
                                "state": resultParks[i].State,
                                "ParkTypeID": resultParks[i].ParkTypeID,
                                "ParkID": resultParks[i].ParkID,
                            });
                        }
                        
                        for (var i = 0; i < resultRegions.length; i++) {
                            results.push({
                                "icon": "pin",
                                "url": resultRegions[i].Url,
                                "title": resultRegions[i].Name,
                            });
                        }

                        for (var i = 0; i < resultDeals.length; i++) {
                            results.push({
                                "icon": "deal",
                                "url": resultDeals[i].Url,
                                "title": resultDeals[i].ResultString,
                            });
                        }

                        for (var i = 0; i < resultArticles.length; i++) {
                            results.push({
                                "icon": "bulb",
                                "url": resultArticles[i].Url,
                                "title": resultArticles[i].Name,
                            });
                        }

                     

                        return results;
                        }).catch(function (error) {
                            Common.ShowError("Unexpected error trying to perform search.");
                            return this.defaultResults;
                        });

              

                    
                }

                if (this.hasRecentlyViewed) {
                    return this.recentlyViewed;
                }
                return this.defaultResults;
            },
        },
    },
    methods: {
        submitSearch:function(data) {
            this.searchString = data;
        },
        GoToUrl:function(item) {
            this.UpdateCookie(item);
            window.location.href = item.url;
        },
        closeKeyBoard: function () {
            this.$nextTick(function () {
                if (document.activeElement == document.getElementById('search'))
                {
                    document.activeElement.blur();
                }
            });
        },
    },
    created: function () {
        var cookie = CookieHelper.GetCookieValue(".BIG4_SAVED_SEARCHES");
        if (cookie != "") {
            cookie = JSON.parse(cookie);
            if (!!cookie.Searches) {
                this.recentlyViewed = cookie.Searches.reverse();
            }
        }

    },
});;
Vue.use(AsyncComputed);

Vue.component('site-search', {
    template: "#SITE_SEARCH_TEMPLATE",
    props: ["scrolled", "home-banner"],
    computed:
    {
        IsScrolled: function () {
            return this.scrolled;
        },
        IsHomeBanner: function ()
        {
            return this.homeBanner;
        },
    },
});;
Vue.component('address-input-component', {
    template: "#AddressInputComponentTemplate",
    mixins: [MIXIN_PRISTINE_VALIDATE],

    data: function () {
        return {
            showSearch: true,
            showAllFields: false,
            addressSearch: "",
            callingApi: false,
            addressesToSelect: [],
            showAddressDropdown: false,
            canCallApi: true,
            addressSelected: false,
            internationalGuest: false,
            address: {
                AddressLine1: "",
                UnitNumber: "",
                StreetNumber: "",
                StreetName: "",
                Suburb: "",
                State: "",
                Postcode: "",
                CountryID: 19 /*Australia*/,

            },
        }
    },
    watch: {
        address: {
            handler: function () {
                var change = false;
                var newAddressLine1 = "";
                if (this.address.UnitNumber != null && this.address.UnitNumber != "") {
                    newAddressLine1 += this.address.UnitNumber + " ";
                    change = true;
                }

                if (this.address.StreetNumber != null && this.address.StreetNumber != "") {
                    newAddressLine1 += this.address.StreetNumber + " ";
                    change = true;
                }

                if (this.address.StreetName != null && this.address.StreetName != "") {
                    newAddressLine1 += this.address.StreetName + " ";
                    change = true;
                }

                if (change) {
                    this.address.AddressLine1 = newAddressLine1.trim();
                }
            },
            deep: true
        },
        addressSearch: function (value) {

            var self = this;
            self.showAddressDropdown = false;
            self.addressSelected = false;
            self.hasError = false;

            var pristine = new Pristine(this.$el)
            var valid = pristine.validate();

            if (valid && this.canCallApi) {
                this.callApi(function (response) {
                    self.addressesToSelect = [];

                    $.each(response.Results, function (i, e) {
                        var item = e;
                        item.Suburb = item.City;
                        self.addressesToSelect.push(item);
                    });

                    self.showAddressDropdown = true;
                    //if (self.addressesToSelect.length > 0) {
                    //    self.showAddressDropdown = true;
                    //}
                });
            }
        }
    },
    methods: {
        setInternationalGuest: function () {
            this.internationalGuest = true;
            this.addressNotFound();
        },
        selectAddress: function (address) {
            var self = this;
            this.canCallApi = false;
            setTimeout(function () {
                self.addressSelected = true;
                self.canCallApi = true;
                self.validate();
            }, 100);

            this.addressSearch = this.presentationAddress(address);
            this.address = address;
            this.address.CountryID = 19;

            this.dismiss();

        },
        addressNotFound: function () {

            this.dismiss();
            this.address.CountryID = 19;
            this.showAllFields = true;
            this.showSearch = false;

        },
        dismiss: function () {
            this.showAddressDropdown = false;
        },
        callApi: _.debounce(function (callback) {
            var self = this;

            this.callingApi = true;
            $.get({
                url: '/api/address/typedown',
                data: { 'request': this.addressSearch },
                dataType: 'json',
                success: function (response) {

                    self.callingApi = false;
                    if (response) {
                        callback(response);
                    }
                },
                error: function () {
                    self.callingApi = false;
                }
            });
        },750),
        presentationAddress: function (address) {
            var presentationAddress = "";

            presentationAddress += address.AddressLine1;

            if (address.AddressLine2 != null && address.AddressLine2 != "") {
                presentationAddress += ", " + address.AddressLine2;
            }
            if (address.City != null && address.City != "") {
                presentationAddress += ", " + address.City;
            }
            if (address.State != null && address.State != "") {
                presentationAddress += ", " + address.State;
            }
            if (address.Postcode != null && address.Postcode != "") {
                presentationAddress += ", " + address.Postcode;
            }

            if (presentationAddress.startsWith(", ")) {
                presentationAddress = presentationAddress.substring(2)
            }

            return presentationAddress;
        },
        populateAddress: function (addressToPopulate) {

            var self = this;
            if (addressToPopulate != null) {

                this.address = JSON.parse(JSON.stringify(addressToPopulate));

                if (!Common.isNullOrEmpty(addressToPopulate.StreetName)
                    && !Common.isNullOrEmpty(addressToPopulate.StreetNumber)
                    && !Common.isNullOrEmpty(addressToPopulate.Suburb)
                    && !Common.isNullOrEmpty(addressToPopulate.State)
                    && !Common.isNullOrEmpty(addressToPopulate.Postcode)
                    || !Common.isNullOrEmpty(addressToPopulate.Address)) {


                    if (this.address.Address && this.address.Address != "") {
                        this.address.AddressLine1 = addressToPopulate.Address;
                    }
                    else {
                        this.address.AddressLine1 = addressToPopulate.UnitNumber + " "
                            + addressToPopulate.StreetNumber + " "
                            + addressToPopulate.StreetName + " ";
                    }

                    if (this.address.AddressLine1 != null)
                        this.address.AddressLine1 = this.address.AddressLine1.trim();

                    this.addressSearch = this.address.AddressLine1 + " "
                        + addressToPopulate.Suburb + " "
                        + addressToPopulate.State + " "
                        + addressToPopulate.Postcode;

                    if (addressToPopulate.CountryID && addressToPopulate.CountryID !== 19 /*Australia*/) {
                        this.internationalGuest = true;
                        this.showAllFields = true;
                        this.showSearch = false;
                        // this.address.Country = addressToPopulate.Country;
                    }

                    if (!addressToPopulate.CountryID || addressToPopulate.CountryID == 0)
                    {
                        this.address.CountryID = 19;
                    }


                    //we need to give time for the watcher to run first
                    setTimeout(function () { self.addressSelected = true; }, 100);
                }
            }
        },
        backToAddressSearch: function () {
            var self = this;

            this.showAllFields = false;
            this.showSearch = true;
            this.internationalGuest = false;
            this.addressSearch = "";
            this.addressSelected = false;
            this.address.CountryID = 19;

            setTimeout(function () {
                self.dismiss();
            }, 100);

        },
        addCustomValidators: function () {
            var self = this;
            var elem = document.getElementById("address");
            if (self.showSearch) {
                self.pristine.addValidator(elem, function (value) {
                    if (self.showSearch) {
                        //check to make sure an address was selected
                        if (!self.addressSelected) {
                            return false;
                        }
                    }

                    return true;
                }, "An address must be selected", 2, false);
            }

        }
    }

});
;
Vue.component('car-hire-data-wrapper', {
    mixins: [MIXIN_CHECK_OVERLAPPING_BOOKINGS],
    props: ["can-sign-up"],
    data: function () {
        return {
            cartState: window.CartStore.state,
            CheckoutState: window.CheckoutStore.state,
            IATA: null,
        }
    },
    computed: {
        startDay: function ()
        {
            return this.CheckoutState.bookingDates.startDate.toDate().getDate()
        },
        endDay: function ()
        {
            return this.CheckoutState.bookingDates.endDate.toDate().getDate()
        },
        startMonth: function ()
        {
            return (this.CheckoutState.bookingDates.startDate.toDate().getMonth() + 1)
        },
        endMonth: function ()
        {
            return (this.CheckoutState.bookingDates.endDate.toDate().getMonth() + 1)
        },
        startYear: function () {
            return this.CheckoutState.bookingDates.startDate.toDate().getFullYear()
        },
        endYear: function ()
        {
            return this.CheckoutState.bookingDates.endDate.toDate().getFullYear()
        },
        iataCode: function ()
        {
            var self = this;

            this.$nextTick(function () {
                $.ajax({
                    type: 'GET',
                    url: '/api/Park/GetParkIATA?parkID=' + self.CheckoutState.bookingDates.parkID,
                    contentType: 'application/json; charset=utf-8',
                    dataType: 'json',
                    success: function (response) {
                        self.IATA = response.IATACode;
                    },
                    error: function (xhr, statusText, err) {
                    }
                });
            });

            return this.IATA;
        },
        iframeUrl: function ()
        {
            var carHireUrl = "https://widget.rentalcars.com/WidgetSearch.do?affiliateCode=big4_rc&adplat=destinationwidget&preflang=en&pickupIATACode="
                + this.iataCode
                + "&results=1"
                + "&pickupMonth=" + this.startMonth
                + "&pickupDate=" + this.startDay
                + "&pickupYear=" + this.startYear
                + "&puHour=9&pickupHour=9&pickupMinute=00"
                + "&returnDate=" + this.endDay
                + "&returnMonth=" + this.endMonth
                + "&returnYear=" + this.endYear
                + "&returnHour=9&returnMinute=00&adplat=pageconf-csl-big4_rc-click";

            return carHireUrl;
        },
        isBookingCompletePage: function ()
        {
            return window.location.href.includes("checkout/complete");
        },
        show: function ()
        {
            if (this.isBookingCompletePage) {
                return this.cartHasAccommodationItems;
            } else {
                return true;
            }
        }
    },
    mounted: function ()
    {
        var self = this;
    }
});
;
Vue.component('covid-check-wrapper', {
    props: ["is-quick-booking"],
    data: function () {
        return {
            showRestrictedCalendar: true,
        }
    },
    computed: {
        covidCalendar: function () {
            return this.$data.showRestrictedCalendar;
        }
    },
    methods:
    {
        covidCanBook: function () {
            var self = this;

            $.ajax({
                type: 'POST',
                url: '/api/Park/CovidCanParkBook?parkDocumentID=' + PARK_DOCUMENT_ID,
                contentType: 'application/json; charset=utf-8',
                success: function (response) {
                    self.$data.showRestrictedCalendar = !response;
                    self.$el.style.display = "inherit";
                    document.getElementById('filterSpinner').style.display = 'none';
                },
                error: function (xhr, ajaxOptions, thrownError) {

                }

            });
        },
        covidCanQuickBook: function () {
            var self = this;
            var parkID = window.BookingStore.state.quickBooking.ParkSelectionID;

            if (window.location.href.includes("/caravan-parks")) {
                var self = this;

                $.ajax({
                    type: 'POST',
                    url: '/api/Park/CovidCanParkBook?parkDocumentID=' + PARK_DOCUMENT_ID,
                    contentType: 'application/json; charset=utf-8',
                    success: function (response) {
                        self.$data.showRestrictedCalendar = !response;
                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                    }

                });
            }

            if (!(parkID == "" || parkID == 0)) {
                $.ajax({
                    type: 'POST',
                    url: '/api/Park/CovidCanParkBook?parkBig4ID=' + parkID,
                    contentType: 'application/json; charset=utf-8',
                    success: function (response) {
                        self.$data.showRestrictedCalendar = !response;
                    },
                    error: function (xhr, ajaxOptions, thrownError) {

                    }

                });
            }
        }
    },
    mounted: function () {
        var self = this;

        this.$nextTick(function () {
            if (self.isQuickBooking) {
                self.covidCanQuickBook();
            }
            else {
                self.$el.style.display = "none";
                self.covidCanBook();
            }
        })



        window.AccommodationEventBus.$on("new-quick-park-selected", function () {
            self.covidCanQuickBook();
        });
    }
});

;
Vue.component('google-map', {
    props: ['props'],

    data: function () {
        return {}
    },
    mounted: function() {
        var self = this;
        if (this.props.coords) {
            // The location
            var location = this.props.coords;

            new AzureMapSinglePin("parkDirectionsMapId", location, 12);
        }
        else {
            var geocoder = new google.maps.Geocoder();

            geocoder.geocode({ 'address': this.props.address }, function (results, status) {
                if (status == 'OK') {
                    var location = { latitude: results[0].geometry.location.lat(), longitude: results[0].geometry.location.lng() };

                    new AzureMapSinglePin("parkDirectionsMapId", location, 12);
                }
            });
        }
    }
});;
Vue.component('google-double-click-slot', {
    props: ["slotId", "tablet", "desktop", "mobile"],
    template: "#GOOGLE_DOUBLE_CLICK_SLOT_TEMPLATE",
    data: function () {
        return {}
    },
    computed: {
        cSlotId: function () {
            if (this.shouldShowAd()) {
                return this.slotId;
            }
            return undefined;
        }
    },
    methods: {
        shouldShowAd: function () {

            if (this.mobile === undefined && this.tablet === undefined && this.desktop === undefined) { return true; }

            if (window.matchMedia("(max-width: 768px)").matches && this.mobile) {
                return true;
            }
            else if (window.matchMedia("(min-width: 769px) and (max-width: 992px)").matches && this.tablet) {
                return true;
            }
            else if (window.matchMedia("(min-width: 993px)").matches && this.desktop) {
                return true;
            }

            return false;
        }
    },
    mounted: function () {
        var self = this;
        if (this.shouldShowAd()) {
            googletag.cmd.push(function () { googletag.display(self.$refs.slot); });
        }




    },

});;
Vue.component('hygiene-badge', {
    props: ["is-park-card", "show-badge"],
    template: '<a v-if="!isParkCard" href="/brandpromise"><img v-show="displayBadge" title="" class="hygiene-badge" src="/Icons/HygieneBadge/brandPromise.png" /></a>\
                <a v-else href="/brandpromise"><img class="hygiene-badge-card" title="" v-show="displayBadge" src="/Icons/HygieneBadge/brandPromise.png" /></a>',
    data: function () {
        return {
            canDisplayBadge: false,
        }
    },
    computed: {
        displayBadge: function () {
            return this.$data.canDisplayBadge;
        }
    },
    methods:
    {
        canDisplay: function ()
        {
            if (this.isParkCard) {
                if (window.location.href.includes("/search")) {
                    this.$data.canDisplayBadge = this.$parent.park.HygieneCertified;
                } else {
                    if (this.$parent.park.HygieneCertified !== undefined) {
                        this.$data.canDisplayBadge = this.$parent.park.HygieneCertified;
                    } else {
                        this.$data.canDisplayBadge = this.$parent.$parent.park.HygieneCertified;
                    }
                }
            } else {
                this.$data.canDisplayBadge = this.showBadge;
            }
        },
    },
    mounted: function () {
        var self = this;

        this.$nextTick(function () {
            self.canDisplay();
        });
    }
});;
/*
    created 31-01-2019 TW
*/
var IdListPickerManager = (function () {

    var instance;

    function init() {
        //######################################
        //# Private methods
        //######################################
        function renderTree(ID, BodyID, FormID, InputID) {
            var contTree = $(ID);
            contTree.jstree();

            applyBindings(ID, BodyID, FormID, InputID);
        }

        function applyBindings(ID, BodyID, FormID, InputID) {
            var input = $(BodyID).parent().find("input.ktc-form-control.myclass");

            $(input).off().on('click', (function () {
                loadLinkPickerModal($(this), ID, BodyID, FormID, InputID);
            }));

        }

        function loadLinkPickerModal(ClickedBox, ID, BodyID, FormID, InputID) {
            //>> Displays content-tree within bootbox dialog >>
            var window = bootbox.dialog({
                title: "Select items below",
                message: $(FormID),
                onEscape: true,
                backdrop: true,
                show: false /* We will show it manually later */,
                buttons: {
                    cancel: {
                        label: 'Cancel',
                        className: 'ktc-btn ktc-btn-default'
                    },
                    confirm: {
                        label: 'Confirm',
                        className: 'ktc-btn ktc-btn-primary',
                        callback: function (result) {
                            //then populates id field after confirm button clicked
                            ClickedBox.val($(InputID).val());
                        }
                    }
                }
            })
            .on('shown.bs.modal', function () {
                $(FormID).show();
            })
            .on('hide.bs.modal', function (e) {
                $(FormID).hide().appendTo($(BodyID));
            }).modal('show');

            //Grabs link and populates text box after clicking tree item using location origin (for web url) and data-url (for page url)
            $(document).on('click', '.jstree-anchor', (function () {
                if ($(InputID).val() == undefined || $(InputID).val().trim().length == 0) {
                    $(InputID).val(($(this).closest('.jstree-anchor').attr('data-val')));
                } else if ($(InputID).val().trim().length > 0 && $(this).closest('.jstree-anchor').attr('data-val') !== undefined) {
                    if (!($(InputID).val().includes($(this).closest('.jstree-anchor').attr('data-val')))) {
                        $(InputID).val($(InputID).val() + ',' + ($(this).closest('.jstree-anchor').attr('data-val')));
                    }
                }
            }));
        }


        //######################################
        //# Private variables
        //######################################
        var tree = null;

        return {
            //######################################
            //# Public variables
            //######################################
            //publicProperty: "I am also public",

            //######################################
            //# Public methods
            //######################################
            LoadTreeNavigation: function (ID, BodyID, FormID, InputID) {
                renderTree(ID, BodyID, FormID, InputID);
            },
        };

    };

    return {
        //Note: Get the instance if one exists or create one if it doesn't
        getInstance: function () {

            if (!instance) {
                instance = init();
            }

            return instance;
        }
    };

})();;
Vue.component('lazy-loading-image', {


    props: ["src", "alt", "srcset", "picture"],
    data: function () {
        return {
            //loadImage: false,
            loading: true,
            observer: null,
            hasLoaded: false,
        }
    },
    template: "#LAZY_LOADING_IMAGE_TEMPLATE",
    watch: {
        src: function () {
            if (this.hasLoaded) {
                this.loadImage();
            }
        }
    },
    methods: {
        isInViewport: function () {
            var bounding = this.$el.getBoundingClientRect();
            return (
                bounding.top >= 0 &&
                //bounding.left >= 0 &&
                bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight)
                //bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
            );
        },
        loadImage: function () {
            this.$refs.image.setAttribute("src", this.src);
            this.hasLoaded = true;
        },
        createObserver: function () {
            var options = {
                root: null,
                threshold: "0",
            };
            window.observer = new IntersectionObserver(this.handleIntersect, options);
            window.observer.observe(this.$el);
        },
        handleIntersect:function(entries, observer) {
            var self = this;
            entries.forEach(function (entry) {
                if (entry.isIntersecting) {
                    self.loadImage();
                    observer.unobserve(self.$el);
                }
            });
        },

    },
    computed: {
        //imageSrc() {
        //    if (this.loadImage) {
        //        return this.src;
        //    }

        //    return "";// this.src;
        //}
    },
    mounted: function () {

        var self = this;
        this.$refs.image.onload = function () {
            self.loading = false;
        }
        

        //document.addEventListener("scroll", function () {
        //    if (self.isInViewport()) {
        //        self.loadImage();
        //    }
        //});

        if (window["IntersectionObserver"]) {
            this.createObserver();
        } else {
            this.loadImage();
        }


    },

});
;
Vue.component('lazy-loading-picture', {


    props: ["src", "alt"],
    data: function () {
        return {
            //loadImage: false,
            loading: true,
            observer: null,
            isVisible: false
        }
    },
    template: "#LAZY_LOADING_PICTURE_TEMPLATE",
    methods: {
        
        loadImage: function () {
            this.$refs.image.setAttribute("src", this.src);
            if (this.src.includes("quality="))
            {
                var pos = this.src.indexOf("quality=");
                var result = this.src.slice(0, pos) + "format=webp&" + this.src.slice(pos);
                this.$refs.imageWebP.setAttribute("srcset", result);
            }
            else
            {
                this.$refs.imageWebP.setAttribute("srcset", this.src + "&format=webp");
            }

            this.isVisible = true;
        },
        createObserver: function () {
            var options = {
                root: null,
                threshold: "0",
            };
            window.observer = new IntersectionObserver(this.handleIntersect, options);
            window.observer.observe(this.$el);
        },
        handleIntersect:function(entries, observer) {
            var self = this;
            entries.forEach(function (entry) {
                if (entry.isIntersecting) {
                    self.loadImage();
                    observer.unobserve(self.$el);
                }
            });
        },

    },
    computed: {
        //imageSrc() {
        //    if (this.loadImage) {
        //        return this.src;
        //    }

        //    return "";// this.src;
        //}
    },
    mounted: function () {

        var self = this;
        this.$refs.image.onload = function () {
            self.loading = false;
        }
        

       
        if (window["IntersectionObserver"]) {
            this.createObserver();
        } else {
            this.loadImage();
        }


    },
    watch: {
        src: function (val) {
            if (this.isVisible) {
                this.loadImage();
            }
        }
    }

});
;
/*
    created 31-01-2019 TW
*/
var LinkPickerManager = (function () {

    var instance;

    function init() {
        //######################################
        //# Private methods
        //######################################
        function renderTree(ID, BodyID, FormID, InputID) {
            var contTree = $(ID);
            contTree.jstree();

            applyBindings(ID, BodyID, FormID, InputID);
        }

        function applyBindings(ID, BodyID, FormID, InputID)
        {
            var input = $(BodyID).parent().find("input.ktc-form-control.myclass");

            $(input).off().on('click', (function ()
            {
                loadLinkPickerModal($(this), ID, BodyID, FormID, InputID);
            }));

        }

        function loadLinkPickerModal(ClickedBox, ID, BodyID, FormID, InputID) {
            //>> Displays content-tree within bootbox dialog >>
            var window = bootbox.dialog({
                title: "Select link below",
                message: $(FormID),
                onEscape: true,
                backdrop: true,
                show: false /* We will show it manually later */,
                buttons: {
                    cancel: {
                        label: 'Cancel',
                        className: 'ktc-btn ktc-btn-default'
                    },
                    confirm: {
                        label: 'Confirm',
                        className: 'ktc-btn ktc-btn-primary',
                        callback: function (result) {
                            //then populates url field after confirm button clicked 
                            ClickedBox.val($(InputID).val());
                        }
                    }
                }
            })
            .on('shown.bs.modal', function () {
                $(FormID).show();
            })
            .on('hide.bs.modal', function (e) {
                $(FormID).hide().appendTo($(BodyID));
            }).modal('show');

            //Grabs link and populates text box after clicking tree item using location origin (for web url) and data-url (for page url)
            $(document).on('click', '.jstree-anchor', (function () {
                $(InputID).val((location.origin + $(this).closest('.jstree-anchor').attr('data-url')));
            }));
        }


        //######################################
        //# Private variables
        //######################################
        var tree = null;
        
        return {
            //######################################
            //# Public variables
            //######################################
            //publicProperty: "I am also public",

            //######################################
            //# Public methods
            //######################################
            LoadTreeNavigation: function (ID, BodyID, FormID, InputID) {
                renderTree(ID, BodyID, FormID, InputID);
            },
        };

    };

    return {
        //Note: Get the instance if one exists or create one if it doesn't
        getInstance: function () {

            if (!instance) {
                instance = init();
            }

            return instance;
        }
    };

})();;
Vue.component('loading-spinner', {
    template: "#LOADING_SPINNER_TEMPLATE",
});
;
//Vue.component('park-card', {

    
//    props:["park"],
//    template: "#PARK_CARD_TEMPLATE",

//    /*
//     * Initial state of the component's data.
//     */
//    data: function () {
//        return {}
//    },
//    computed: {
//        isMobile:function() {
//            return false;
//        },
//        showImageCarousel: function () {
//            if (this.isMobile) {
//                return false;
//            }
//            else {
//                if (this.park.Images.length > 1) {
//                    return true;
//                }
//            }

//            return false;
//        },
//        images: function () {
//            var result = [];
//            var self = this;

//            $.each(this.park.Images, function (i, e) {
//                result.push({
//                    Image: e,
//                    Url: self.park.ParkUrl,
//                })
//            });

//            return result;
//        },
//        firstImage: function () {
//            return this.images[0];
//        },
//        parkId: function () {
//            return this.park.ParkID;
//        }
//    },
//    methods: {

//    },
//    mounted: function () {
//    },
//    beforeDestroy: function () {
//    },

//});
;
Vue.component('park-card-pricing', {
    template: "#PARK_CARD_PRICING_TEMPLATE",
    mixins: [MIXIN_MEMBERSHIP],
    props:['park-price'],
    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {}
    },
    computed: {
        price: function () {
            //Assume sites are cheapest
            //if (this.parkPrice.length == 0)
            //    return "-";

            //lowestNodeIndex = 0;
            //for (var count = 0; count < this.parkPrice.length; count++)
            //{
            //    if (this.parkPrice[count].Name.includes("Sites")) {
            //        lowestNodeIndex = count;
            //        break;
            //    }
            //}
            //for (var count = 0; count < this.parkPrice[lowestNodeIndex].length; count++) {
            //    if (this.parkPrice[lowestNodeIndex].Prices[count].Name.includes("Standard")) {
            //        return this.parkPrice[lowestNodeIndex].Prices[count].Price;
            //    }
            //    else
            //        return this.parkPrice[lowestNodeIndex].Prices[count].Price;
            //}
            //return this.parkPrice[0].Prices[0].Price;
            return this.RoundPrice(this.parkPrice.Price);
        },
        discountPrice: function () {
            //Assume sites are cheapest
            //if (this.parkPrice.length == 0)
            //    return "-";

            //lowestNodeIndex = 0;
            //for (var count = 0; count < this.parkPrice.length; count++) {
            //    if (this.parkPrice[count].Name.includes("Sites")) {
            //        lowestNodeIndex = count;
            //        break;
            //    }
            //}
            //for (var count = 0; count < this.parkPrice[lowestNodeIndex].length; count++) {
            //    if (this.parkPrice[lowestNodeIndex].Prices[count].Name.includes("Standard") == false) {
            //        return this.parkPrice[lowestNodeIndex].Prices[count].Price;
            //    }
            //    else
            //        return this.parkPrice[lowestNodeIndex].Prices[count].Price;
            //}
            //return this.parkPrice[0].Prices[1].Price;
            return this.RoundPrice(this.parkPrice.DiscountPrice);
        },
        accommodationTypeText: function ()
        {
            //This returns relevant text if the price is being displayed for specific users (e.g. cabins/site users)
            if (this.parkPrice.AccommodationTypeText != null) {
                return this.parkPrice.AccommodationTypeText;
            } else {
                return "";
            }
        }
    },
    methods: {

        showMemberPrice: function () {
            return (this.isLoggedIn && !this.isHolidayPerksMember) || this.isMemberOnlyDeal;
        },
        memberPriceNotEqualToNonMember: function () {
            return !(this.discountPrice == this.price);
        },
        memberIsVIPerks: function ()
        {
            return (this.isLoggedIn && this.isVipPerksMember);
        }
    }
});
;
Vue.component('park-card-pricing-accommodation', {
    template: '#ParkCardPricingAccommodationTemplate',
    mixins: [MIXIN_MEMBERSHIP],
    props: ['park-price', 'park', 'loading'],
    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {
            signalRPrice: null,
            cabinsMinStayNotMet: false,
            sitesMinStayNotMet: false,
            cabinsMinNightsStay: 0,
            sitesMinNightStay: 0,
        }
    },

    computed: {
        cabin: function () {
            if (this.signalRPrice != null && this.signalRPrice.length > 0 && this.dateFilterApplied) {
                return this.cheapestSignalRAccommodationForType(1);
            }
            else {
                return this.cheapestAccommodationForType("Cabins");
            }
        },
        site: function () {
            if (this.signalRPrice != null && this.signalRPrice.length > 0 && this.dateFilterApplied) {
                return this.cheapestSignalRAccommodationForType(2);
            }
            else {
                return this.cheapestAccommodationForType("Sites");
            }
        },
        dateFilterApplied: function ()
        {
            var result = window.DateFilterStore.state.dateFilterApplied;
            return result;
        },
        cabinsUnavailable: function () {
            if (this.signalRPrice != null && this.signalRPrice.length > 0) {
                if (!window.DateFilterStore.state.dateFilterApplied)
                {
                    //Check if guest filter is applied, if it is and the 
                    if (!window.GuestFilterStore.isApplied) {
                        return false;
                    }
                }

                return !this.isAvailableForType(1);
            }

            return false; !window.DateFilterStore.state.dateFilterApplied
        },
        cheapestCachePrice: function ()
        {
            //Determines the cheapest cache price for use when datefilter is not applied
            var self = this;
            var result = this.signalRPrice;
            if (self.cheapestAccommodationForType("Sites") != undefined && self.cheapestAccommodationForType("Cabins") != undefined) {
                if (self.cheapestAccommodationForType("Sites").Standard == undefined && self.cheapestAccommodationForType("Cabins").Standard != undefined) {
                    return this.cheapestAccommodationForType("Cabins")
                }
                else if (self.cheapestAccommodationForType("Sites").Standard != undefined && self.cheapestAccommodationForType("Cabins").Standard == undefined) {
                    return this.cheapestAccommodationForType("Sites")
                } else if (self.cheapestAccommodationForType("Sites").Standard != undefined && self.cheapestAccommodationForType("Cabins").Standard != undefined)
                {
                    if (parseInt(self.cheapestAccommodationForType("Sites").Standard.replace("$", "")) < parseInt(self.cheapestAccommodationForType("Cabins").Standard.replace("$", ""))) {
                        return this.cheapestAccommodationForType("Sites")
                    } else {
                        return this.cheapestAccommodationForType("Cabins")
                    }
                }
            }
            else return { Standard: "$", Discount: "$" }
        },
        cheapest: function () {
            //Either the cheapest cache overall price, or cheapest signalRPrice depending on whether filter is applied.
            //Used for mobile search result pricing
            this.$parent.setPriceLoading();

            if (this.signalRPrice != null && this.signalRPrice.length > 1)
            {
                var sitePrice = "";

                var cabinPrice = "";
                var result = null;
                
                sitePrice = this.cheapestSignalRAccommodationForType(2);
                cabinPrice = this.cheapestSignalRAccommodationForType(1);

                if (sitePrice != null && cabinPrice != null) {
                    var sitePriceString = sitePrice.Standard;
                    var cabinPriceString = cabinPrice.Standard;

                    var sitePriceInt = 0;
                    var cabinPriceInt = 0;                    

                    if (!Common.isNullOrEmpty(sitePriceString)) {
                        sitePriceInt = parseInt(sitePriceString.replace("$",""));
                    }
                    if (!Common.isNullOrEmpty(cabinPriceString)) {
                        cabinPriceInt = parseInt(cabinPriceString.replace("$", ""));
                    }
                    

                    //If we do not have the date filter applied, we do not care about checking availibility for types
                    if (!window.DateFilterStore.state.dateFilterApplied) {
                        

                        if (sitePriceInt < cabinPriceInt) {
                            result =  sitePrice;
                        } else if (this.isAvailableForType(1)) {
                            result =  cabinPrice;
                        }
                    }

                    if ((sitePriceInt < cabinPriceInt) && sitePrice && this.isAvailableForType(2)) {
                        result =  sitePrice;
                    } else if(this.isAvailableForType(1)){
                        result =  cabinPrice;
                    }
                }
                else if (sitePrice != null && this.isAvailableForType(2))
                {
                    result =  sitePrice;
                }
                else if (cabinPrice != null && this.isAvailableForType(1))
                {
                    result =  cabinPrice;
                }
                else
                {
                    result =  { Standard: "null", Discount: "null" };
                }

            } else if (window.DateFilterStore.state.dateFilterApplied)
            {
                result =  { Standard: "null", Discount: "null" };
            }
            else if (this.cheapestCachePrice != null)
            {
                result =  this.cheapestCachePrice;
            }

            this.$parent.setPriceFinishedLoading();
            return result;
        },
        sitesUnavailable: function () {
            if (this.signalRPrice != null && this.signalRPrice.length > 0) {
                if (!window.DateFilterStore.state.dateFilterApplied)
                {
                    return false;
                }
                return !this.isAvailableForType(2);
            }
            return false;
        },
        isUnavailable: function () {
            if (this.signalRPrice != null && this.signalRPrice.length > 0) {
                return (this.sitesUnavailable && this.cabinsUnavailable)
            }
            else {
                //we never show "unavailable" for the default dates
                return false;
            }

        },
        isCabinsMinStayNotMet: function () {
            return this.cabinsMinStayNotMet;
        },
        isSitesMinStayNotMet: function () {
            return this.sitesMinStayNotMet;
        }
    },
    methods: {
        updatePriceFromSignalR: function (data) {
            this.signalRPrice = data;
            //Force update required as vue would not correctly update
            //Price data on mobile without forced update
            this.$forceUpdate();
        },
        isAvailableForType: function (type) {
            for (var count = 0; count < this.signalRPrice.length; count++) {
                if (this.signalRPrice[count].Allotment != null) {
                    for (var allotmentCount = 0; allotmentCount < this.signalRPrice[count].Allotment.length; allotmentCount++) {
                        if (this.signalRPrice[count].Allotment[allotmentCount].SiteTypeID == type) {
                            if (this.signalRPrice[count].Allotment[allotmentCount].IsAvailable) {
                                return true;
                            } else if (!this.signalRPrice[count].Allotment[allotmentCount].IsStayLengthMet) {
                                if (type === 1) {
                                    this.cabinsMinStayNotMet = true;

                                    //If cabinsMinNightsStay is 0 then we want to add the Min Nights Stay for this accommodation so we can show the min nights stay
                                    //If it is >0 then we want to set it back to 0 so we can show a more generic message
                                    if (!this.cabinsMinNightsStay || this.cabinsMinNightsStay === 0 || this.cabinsMinNightsStay > this.signalRPrice[count].Allotment[allotmentCount].MinStay) {
                                        this.cabinsMinNightsStay = this.signalRPrice[count].Allotment[allotmentCount].MinStay;
                                    }

                                } else {
                                    this.sitesMinStayNotMet = true;

                                    //If sitesMinNightsStay is 0 then we want to add the min nights stay for this accommodation so we can show the min nights stay
                                    //If it is >0 then we want to set it back to 0 so we can show a more generic message
                                    if (!this.sitesMinNightsStay || this.sitesMinNightsStay === 0 || this.sitesMinNightsStay > this.signalRPrice[count].Allotment[allotmentCount].MinStay) {
                                        this.sitesMinNightsStay = this.signalRPrice[count].Allotment[allotmentCount].MinStay;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return false;
        },
        cheapestAccommodationForType: function (type) {
            var lowestNodeIndex = -1;
            for (var count = 0; count < this.parkPrice.length; count++) {
                if (this.parkPrice[count].Name.includes(type)) {
                    lowestNodeIndex = count;
                    break;
                }
            }

            if (lowestNodeIndex == -1) {
                return "-";
            }


            var prices = {
                Standard: "$" + this.RoundPrice(this.parkPrice[lowestNodeIndex].Prices[0].Price).toString(),
                Discount: "$" + this.RoundPrice(this.parkPrice[lowestNodeIndex].Prices[1].Price).toString(),
                //IsAvailable: this.parkPrice[lowestNodeIndex].Prices[0].Price,
            }

            return prices;

        },
        cheapestSignalRAccommodationForType:function(type) {
            try {
                var lowestPrice = 100000;
                var lowestAccommodationIndex = -1;
                var lowestAllotmentIndex = -1;
                for (var count = 0; count < this.signalRPrice.length; count++) {
                    for (var allotmentCount = 0; allotmentCount < this.signalRPrice[count].Allotment.length; allotmentCount++) {
                        if (this.signalRPrice[count].Allotment[allotmentCount].SiteTypeID == type) {
                            if (this.signalRPrice[count].Allotment[allotmentCount].IsAvailable) {
                                if (this.signalRPrice[count].Allotment[allotmentCount].Total < lowestPrice) {
                                    lowestPrice = this.signalRPrice[count].Allotment[allotmentCount].Total;
                                    lowestAccommodationIndex = count;
                                    lowestAllotmentIndex = allotmentCount;
                                }
                            }
                            //break;
                        }
                    }
                }

                if (lowestAllotmentIndex == -1) {
                    return "-";
                }

                var prices = {
                    Standard: "$" + this.RoundPrice(this.signalRPrice[lowestAccommodationIndex].Allotment[lowestAllotmentIndex].Total).toString(),
                    Discount: "$" + this.RoundPrice(this.signalRPrice[lowestAccommodationIndex].Allotment[lowestAllotmentIndex].TotalWithDiscount).toString(),
                    //IsAvailable: this.parkPrice[lowestNodeIndex].Prices[0].Price,
                }
            }
            catch (err) {
                prices = null;
            }
            return prices;
        },
    },

});
;
//Vue.component('park-search-card', {

//    mixins:[MIXIN_SEARCH_SAVED_SEARCHES],
//    props: ["park"],
    
//    template: '#ParkSearchCardTemplate',

//    data: function () {
//        return {
//            state: window.SearchStore.state,
//            priceLoading: false,
//            pricingUnavailable: false,
//        }
//    },
//    computed: {

//        isMobile: function () {
//            return false;
//        },
//        showImageCarousel: function () {
//            if (this.isMobile) {
//                return false;
//            }
//            else {
//                if (this.park.Images.length > 1) {
//                    return true;
//                }
//            }

//            return false;
//        },
//        images: function () {
//            var result = [];
//            var self = this;

//            $.each(this.park.Images, function (i, e) {
//                result.push({
//                    Image: e,
//                    Url: self.park.ParkUrl,
//                })
//            });

//            return result;
//        },
//        firstImage: function () {
//            return this.images[0];
//        },
//        parkId: function () {
//            return this.park.ParkID;
//        },
//        unavailableReason: function () {
//            var self = this;
//            //First determine if min nights stay is not met
//            if (self.$refs.pricing && (self.$refs.pricing.cabinsMinStayNotMet || self.$refs.pricing.sitesMinStayNotMet)) {
//                //The determine if we need to show a specific date
//                if ((self.$refs.pricing.cabinsMinNightsStay) && ((!self.$refs.pricing.sitesMinNightsStay) || self.$refs.pricing.cabinsMinNightsStay <= self.$refs.pricing.sitesMinNightsStay)) {
//                    return self.$refs.pricing.cabinsMinNightsStay + " night minimum stay required";
//                } else if ((self.$refs.pricing.sitesMinNightsStay) && ((!self.$refs.pricing.cabinsMinNightsStay) || self.$refs.pricing.sitesMinNightsStay <= self.$refs.pricing.cabinsMinNightsStay)) {
//                    return self.$refs.pricing.sitesMinNightsStay + " night minimum stay required";
//                } else {
//                    return "Unavailable";
//                }
//            } else {
//                return "Unavailable";
//            }
//        },
//        props: function () {
//            return {
//                GoToUrl: this.GoToUrl
//            };
//        }
//    },
//    methods: {

//        isUnAvailable: function () {
//            var self = this;

//            if ((this.pricingUnavailable && window.DateFilterStore.state.dateFilterApplied) || !this.park.IsAvailable) {
//                return true;
//            }

//            if (self.$refs.pricing && (!self.$refs.pricing.cabin || self.$refs.pricing.cabin == "-") && (!self.$refs.pricing.site || self.$refs.pricing.site == "-")) {
//                return true;
//            }

//            return false;
//        },

//        updatePrice:function(data) {
//            if (typeof this.$refs.pricing !== 'undefined') {
//                this.$refs.pricing.updatePriceFromSignalR(data.AllAccommodations);
//            }
//            this.setPriceFinishedLoading();
//        },
//        clearPrice: function () {
//            if (typeof this.$refs.pricing !== 'undefined') {
//                this.$refs.pricing.updatePriceFromSignalR(null);
//            }
//            this.setPriceFinishedLoading();
//        },
//        setPriceLoading: function () {
//            this.priceLoading = true;
//        },
//        setPriceFinishedLoading: function () {
//            this.priceLoading = false;
//        },
//        GoToUrl: function () {
//            this.UpdateCookie({
//                url: this.park.Url,
//                title: this.park.ParkName,
//                icon:'big4'
//            });

//            window.location.href = this.park.Url;
//        }
//    },
//    mounted: function () {
//        var self = this;

//        if (!!window.SearchEventBus) {
//            window.SearchEventBus.$emit(window.SearchEvents.SUBSCRIBE_TO_SIGNALR, this);
//        }

//        if (!!window.SearchResultsAndFiltersEventBus) {
//            window.SearchResultsAndFiltersEventBus.$emit(window.SearchResultsAndFiltersEvents.SUBSCRIBE_TO_SIGNALR, this);
//        }

//        if (SEARCH_PARK_BIG4IDS.length < 5)
//        {
//            SEARCH_PARK_BIG4IDS.push(this.parkId);
//        }


//        this.$watch("$refs.pricing.isUnavailable", function () {
//            self.pricingUnavailable = self.$refs.pricing.isUnavailable;
//        });

//        window.SearchEventBus.$on('date-filter-clear', function (data) {
//            self.setPriceLoading(true);
//            self.clearPrice();
//        });

//        window.SearchResultsAndFiltersEventBus.$on('date-filter-clear', function (data) {
//            self.setPriceLoading(true);
//            self.clearPrice();
//        });

//    },
//    beforeDestroy: function () {
//        if (!!window.SearchEventBus) {
//            window.SearchEventBus.$emit(window.SearchEvents.UNSUBSCRIBE_FROM_SIGNALR, this);
//        }

//        if (!!window.SearchResultsAndFiltersEventBus) {
//            window.SearchResultsAndFiltersEventBus.$emit(window.SearchResultsAndFiltersEvents.UNSUBSCRIBE_FROM_SIGNALR, this);
//        }
//    },

//});
;
Vue.component('park-type-badge', {

    props: ['park-type'],

    template: "#PARK_TYPE_BADGE_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {}
    },
    computed: {
        Enums: function () {
            return window.Enums;
        }
    },
    methods: {

    }

});
;
Vue.component('price-guarantee', {
    props: {
        withBorder: {
            default: true,
        },
        withLink:
        {
            default: true,
        },
        optedIn: {
            default: false,
        },
        covidParkCanBook: {
            default: false,
        },
        showOptInCovidBanner: {
            default: false,
        },
        widgetVersion: {
            default: false,
        },
        parkBookingTermsUrl: {
            default: "",
        },
        freeMembership : {
            default: false,
        }
    },
    template: "#PRICE_GUARANTEE_TEMPLATE",
    computed:
    {
        selectionMade: function ()
        {
            //TW: We check the current cart for any accommodations
            var result = false;

            if (window.CartStore.state.cartItems.length > 0)
            {
                for (var i = 0; i < window.CartStore.state.cartItems.length; i++)
                {
                    if (window.CartStore.state.cartItems[i].CartItemTypeID == window.CartItemType.ACCOMMODATION)
                    {
                        result = true;
                    }
                }
            }

            return result;
        },
        WithLink: function ()
        {
            //TW: If we are in the checkout, remove the link
            if ($('.c-header--checkout').length > 0) {
                this.withLink = false;
            }
            return this.withLink;
        },
        isFreeMembership: function () {
            return this.freeMembership;
        },
        WithBorder: function ()
        {
            //TW: Returns border/borderless banner
            return this.withBorder;
        },
        OptedIn: function ()
        {
            return this.optedIn;
        },
        CovidParkCanBook: function ()
        {
            return this.covidParkCanBook;
        },
        ShowOptInCovidBanner: function ()
        {
            return this.showOptInCovidBanner;
        },
        ParkTerms: function() {
            return this.parkBookingTermsUrl;
        },
        validForCheckout: function ()
        {
            var valid = false; 

            if (window.CartStore == undefined || !window.location.href.includes("/checkout")) {
                return valid;
            } else {
                for (var i = 0; i < window.CartStore.state.cartItems.length; i++)
                {
                    if (window.CartStore.state.cartItems[i].CartItemTypeID == 1 && window.CartStore.state.cartItems[i].CancellationPolicyOption == true) {
                        valid = true;
                    } else if (window.CartStore.state.cartItems[i].CartItemTypeID == 1 && window.CartStore.state.cartItems[i].CancellationPolicyOption == false) {
                        valid = false;
                    }
                }
            }

            return valid;
        },
        checkoutTermsUrls: function ()
        {
            var result = [];

            if (this.validForCheckout)
            {
                for (var i = 0; i < window.CartStore.state.cartItems.length; i++) {
                    if (window.CartStore.state.cartItems[i].CartItemTypeID == 1) {

                        if (i == (window.CartStore.state.cartItems.length - 1))
                        {
                            result.push({ ParkName: window.CartStore.state.cartItems[i].ParkName, Url: window.CartStore.state.cartItems[i].ParkTermsAndConditionsURL, Breaker: "" });
                        } else {
                            result.push({ ParkName: window.CartStore.state.cartItems[i].ParkName, Url: window.CartStore.state.cartItems[i].ParkTermsAndConditionsURL, Breaker: ", and" });
                        }
                    } else {
                        valid = false;
                    }
                }
            }
            return result;
        },
    },
    methods:
    {
    },
    mounted: function ()
    {
        var self = this;

        window.BookingEventBus.$on('free-membership-update', function(data) {
            self.freeMembership = data;
        });
    }
});;
Vue.component('show-on-scroll', {
    props: ["props"],
    template:"#SHOW_ON_SCROLL_TEMPLATE",
    data: function () {
        return {
            showOnScroll:false,
            observer:null,
        }
    },
    methods: {
        
        createObserver: function () {
            var options = {
                root: null,
                threshold: "0",
            };
            this.observer = new IntersectionObserver(this.handleIntersect, options);
            this.observer.observe(this.$el);
        },
        handleIntersect:function(entries, observer) {
            var self = this;
            entries.forEach(function (entry) {
                if (entry.isIntersecting) {
                    self.showOnScroll = true;
                    self.observer.unobserve(self.$el);
                }
            });
        },

    },
   
    mounted: function () {

        var self = this;
        

        if (window["IntersectionObserver"]) {
            this.createObserver();
        } else {
            this.showOnScroll = true;
        }


    },

});
;
Vue.component('star-rating', {

    props: ['rating'],

    template: "#STAR_RATING_TEMPLATE",

    /*
     * Initial state of the component's data.
     */
    data: function () {
        return {}
    },

    methods: {
       
    }

});
;
Vue.component('state-level-message', {
    props: {
        optedIn: {
            default: false,
        },
        covidParkCanBook: {
            default: false,
        },
        showOptInCovidBanner: {
            default: false,
        },
        brandPromise: {
            default: false,
        },
        parkBookingTermsUrl: {
            default: "",
        },
        messageTitle: {
            default: "",
        },
        standardStateLevelMessage: {
            default: "",
        },
        brandPromiseStateLevelMessage: {
            default: "",
        }
    },
    template: "#STATE_LEVEL_MESSAGE_TEMPLATE",
    computed:
    {
        OptedIn: function ()
        {
            return this.optedIn;
        },
        ParkTerms: function () {
            return this.parkBookingTermsUrl;
        },
        CovidParkCanBook: function ()
        {
            return this.covidParkCanBook;
        },
        ShowOptInCovidBanner: function ()
        {
            return this.showOptInCovidBanner;
        },
        BrandPromise: function () {
            return this.brandPromise;
        },
        State: function () {
            return window.location.href.split('/')[4].toUpperCase();
        },
        ParkAlias: function () {
            return window.location.href.split('/')[6];
        },
        MessageText: function () {
            if (this.brandPromiseStateLevelMessage != "" && this.brandPromise) {
                return this.brandPromiseStateLevelMessage;
            } else if (this.standardStateLevelMessage != "" && (!this.brandPromise || this.brandPromiseStateLevelMessage == "")) {
                return this.standardStateLevelMessage;
            }
        }
    },
    methods:
    {
    },
    mounted: function ()
    {
    }
});;
Vue.component('virtual-tour-button', {

    
    props: [],
    template: '#VirtualTourTemplate',

    data: function () {
        return {}
    },
    methods: {

        
    },
    created:function() {

  
    }

});;
Vue.component('vr-view', {


    props: ["virtual-tour-url", "document-id"],
    data: function () {
        return {
            tourType: '',
            tourUrl: '',
            tourName: '',
        }
    },
    computed:
    {
        TourType: function () {
            return this.tourType;
        },
        TourUrl: function () {
            return this.tourUrl;
        },
        TourName: function () {
            return this.tourName;
        }
    },
    methods: {
        loadVirtualTour: function (url) {
            var vrView = new VRView.Player('#vrview', {
                width: '100%',
                height: 500,
                //preview: 'http://big4servicesdemoext.acceleon.com.au:8070/big4/media/images/IMG_20151213_154056.vr-converted.jpg',
                //image: 'http://big4servicesdemoext.acceleon.com.au:8070/big4/media/images/IMG_20151213_154056.vr-converted.jpg',
                //preview: 'https://storage.googleapis.com/vrview/examples/coral-preview.jpg',
                image: url,

                is_stereo: true
            });
        }
    },
    created: function () {
        var url = this.virtualTourUrl;

        var data =
        {
            //TW: Change from hard coded value to take DocumentID
            documentId: DOCUMENT_ID
        }

        var self = this;

        $.ajax({
            type: 'GET',
            url: '/api/VirtualTour/GetVirtualTour/' + data.documentId,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (response) {
                self.tourType = response.Type;
                self.tourUrl = response.Url;
                self.tourName = response.Name;
            },
            error: function (xhr, statusText, err) {
            }
        });
    }

});;
Vue.component('quantity-warning', {
    template: '#QUANTITY_WARNING_TEMPLATE',
    props: {
        isAccomCard: false,
        isBookingWidget: false,
        isQuickBooking: false,
        isCart: false,
        accommodationId: null,
    },
    data: function() {
        return {
            allotmentAmount: 0,
        }
    },
    computed: {
        sellingFast: function() {
            return this.allotmentAmount <= 4 && this.allotmentAmount > 1;
        },
        lastOne: function () {
            return this.allotmentAmount == 1;
        },
        accommodationCard: function () {
            return this.isAccomCard;
        },
        bookingWidget: function () {
            return this.isBookingWidget;
        },
        cart: function () {
            return this.isCart;
        },
        display: function () {
            return this.sellingFast || this.lastOne;
        },
        quantity: function () {
            return this.allotmentAmount;
        }
    },
    mounted: function () {

        var self = this;

        //Different listener events depending on variation

        if (this.isQuickBooking) {
            window.AccommodationEventBus.$on('quantity-update', function (data) {
                //Only update if this card matches the accommodation data
                if (data.accommodationID == self.$props.accommodationId)
                {
                    self.allotmentAmount = data.quantity
                }
            });
        }
        else if (this.isAccomCard) {
            window.AccommodationEventBus.$on('quantity-update', function (data) {
                if (data.accommodationID == self.$props.accommodationId) {
                    self.allotmentAmount = data.quantity
                }
            });

            window.AccommodationEventBus.$on('quantity-clear', function () {
                self.allotmentAmount = 0;
            });
        }
        else if (this.isCart)
        {
            for (var i = 0; i < window.CartStore.state.cartItems.length; i++)
            {
                if (window.CartStore.state.cartItems[i].TransactionLineItem.Booking.AccommodationID == self.accommodationId)
                {
                    self.allotmentAmount = window.CartStore.state.cartItems[i].TransactionLineItem.Booking.maxNumberOfRooms;
                }
            }
        }
        else {
            window.BookingEventBus.$on('quantity-update', function (data) {
                self.allotmentAmount = data.quantity
            });

            if (this.$mq == 'sm') {
                window.BookingStore.InitialQuantityCheck();
            }
        }
    }
});;
Vue.component('something-for-everyone-widget', {
    props: ['categories', 'articles', 'title'],
    template: '#SOMETHING_FOR_EVERYONE_WIDGET_TEMPLATE',
    data: function () {
        return {
            currentCategory: null
        }
    },
    methods:
    {
        navigate: function (category) {
            this.currentCategory = category.Value;
        },
        isActive: function (categoryGuid) {
            return this.currentCategory === categoryGuid;
        },
        articlesForCategory: function (category) {
            return _.filter(this.articles, function (item) {
                return item.CategoryGuid === category;
            });
        }
    },
    mounted: function() {
        if (this.categories.length > 0) {
            this.currentCategory = this.categories[0].Value;
        }
    }
})

;
Vue.component('quick-booking-data-wrapper', {
    props:["props"],
    data: function () {
        return {
            state: window.BookingStore.state,
        }
    },
    computed: {
    },
    methods: {
        populateSearchWithPark: function ()
        {
            var self = this;
            //If our state contains a selected park, display this as the search value
            if (this.state.quickBooking.ParkSelectionName != "") {
                var searchBar = document.getElementById("quickSearch");
                setTimeout(function () {
                    searchBar.value = self.$data.state.quickBooking.ParkSelectionName;
                }, 650);
            }
        }
    },
    created: function () {
    },
    mounted: function ()
    {
        this.populateSearchWithPark();
    },

});;
Vue.component('quick-booking-widget', {
    template: "#QUICK_BOOKING_WIDGET_TEMPLATE",
    props: {
        parkWidget: false,
    },
    computed: {
        isPark: function ()
        {
            return this.parkWidget;
        },
        props: function ()
        {
            return {
                isPark: this.isPark,
            }
        }
    },
    data: function () {
        return {
            store: window.BookingStore,
            windowWidth: 0,
        }
    },
    methods: {
        prefillPark: function () {

        },
    },
    created: function () {
        this.store.PopulateEquipmentTypes();
        this.store.prefillSelections();

        //Toggles park specific logic for quick booking widget
        if (this.isPark) {
            this.store.state.quickBooking.isPark = true;
        } else {
            this.store.state.quickBooking.isPark = false;
        }
    },
    mounted: function ()
    {
        if (CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES") != "") {
            if (CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES") != "") {
                var cookie = JSON.parse(CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES"));

                if (cookie.Dates != null && cookie.Dates.start != "" && cookie.Dates.end != "") {
                    this.store.startDate = cookie.Dates.start;
                    this.store.endDate = cookie.Dates.end;
                }
            }
        }
    },
});;
Vue.component('quick-booking-search', {
    template: "#QUICK_BOOKING_SEARCH_TEMPLATE",
    props: ["scrolled", "home-banner"],
    computed:
    {
        state: function()
        {
            return window.BookingStore.state;
        },
    },
    mounted: function ()
    {
    }
});;
Vue.use(AsyncComputed);

Vue.component('quick-booking-search-data-wrapper', {
    mixins: [MIXIN_SEARCH_SAVED_SEARCHES],
    props: {
        account: {
            type: Object,
            default: function () {
                return {}
            },
        },
        defaultResults: {
            type: Array,
            default: function () { return [] },
        },
        store: window.BookingStore,
    },
    data: function () {
        return {
            searchString: '',
            error: '',
            request: [],
            recentlyViewed: [],
        };
    },
    computed: {
        isPark: function ()
        {
            return this.props.store.state.quickBooking.isPark;
        },
        hasRecentlyViewed: function () {
            //return this.recentlyViewed.length > 0 && this.searchString.length == 0;
            //return false for the time being to avoid pre-existing user cookies causing errors
            return false
        },
        props: function () {
            return {
                RecentlyViewed: this.recentlyViewed,
                HasRecentlyViewed: this.hasRecentlyViewed,
                SelectPark: this.SelectPark,
                IsScrolled: this.scrolled,
                IsHomeBanner: this.homeBanner,
                CloseKeyBoard: this.closeKeyBoard,
                SelectPark: this.SelectPark,
                store: window.BookingStore,
            }
        }
    },
    asyncComputed: {
        data: {
            get:function() {
                const partnerParkTypeID = window.Enums.ParkTypeEnum['Affiliate'];
                var results = [];
                var startDate = moment().format(); // Today's date (ISO format)
                var tomorrowDate = moment().add(1, 'day').format();

                if (this.searchString.length > 0) {

                    return axios.get('/api/Search/ParkSearchUri', {
                        params: {
                            SearchTerm: this.searchString,
                            StartDate: startDate,
                            EndDate: tomorrowDate,
                            PetFriendly: "",
                            States: "",
                            Latitude: "",
                            Longitude: "",
                            MaxDistanceRange: "",
                            PageNumber: "",
                            ResultsPerPage: ""
                        }
                    }).then(function (response) {
                        response = JSON.parse(response.data);

                        var resultParks = response.Parks;
                        var length = resultParks.length;

                        if (length > 5)
                        {
                            length = 5;
                        }

                        for (var i = 0; i < length; i++) {
                            results.push({
                                "icon": resultParks[i].ParkTypeID === partnerParkTypeID ? 'handshake' : "big4",
                                "url": resultParks[i].Url,
                                "title": resultParks[i].ParkName,
                                "location": resultParks[i].Location,
                                "state": resultParks[i].State,
                                "ParkTypeID": resultParks[i].ParkTypeID,
                                "ParkID": resultParks[i].ParkID,
                            });
                        }

                        return results;
                        }).catch(function (error) {
                            Common.ShowError("Unexpected error trying to perform search.");
                            return this.defaultResults;
                        });
                }

                if (this.hasRecentlyViewed) {
                    return this.recentlyViewed;
                }
                return this.defaultResults;
            },
        },
    },
    methods: {
        submitSearch:function(data) {
            this.searchString = data;
        },
        SelectPark: function (parkObject) {
            //Get accommodations for park
            var self = this;

            $.ajax({
                type: 'GET',
                url: '/api/Park/GetAccommodations',
                contentType: 'application/json; charset=utf-8',
                data: {
                    parkID: parkObject.ParkID,
                    parkUrl: parkObject.url,
                },
                dataType: 'json',
                success: function (response) {
                    window.AccommodationStore.state.accommodations = response;
                    window.AccommodationEventBus.$emit("accommodations-loaded");
                    window.AccommodationStore.state.ParkId = parkObject.ParkID;
                    window.BookingStore.state.accommodation = response;
                },
                error: function (xhr, statusText, err) {
                }
            });

            //store the default values in cookie
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie["QuickBookingParkID"] = [parkObject.ParkID];
                cookie["QuickBookingParkName"] = [parkObject.title];
                cookie["QuickBookingParkURL"] = [parkObject.url];
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }

            this.props.store.state.quickBooking.ParkSelectionID = parkObject.ParkID;
            this.props.store.state.quickBooking.ParkSelectionName = parkObject.title;

            //Replaces the typed search with the chosen park name
            //Timeout is used to prevent the search resetting to the typed value
            this.updateSearchText();

            window.AccommodationEventBus.$emit("new-quick-park-selected");
        },
        PrefillPark: function (parkDocumentID)
        {
            //Get accommodations for park
            var self = this;

            $.ajax({
                type: 'GET',
                url: '/api/Park/GetAccommodationsFromDocumentID',
                contentType: 'application/json; charset=utf-8',
                data: {
                    parkDocumentID: parkDocumentID,
                },
                dataType: 'json',
                success: function (response) {
                    window.AccommodationStore.state.accommodations = response.Accommodation;
                    window.AccommodationEventBus.$emit("accommodations-loaded");
                    window.AccommodationStore.state.ParkId = response.ParkID;
                    window.BookingStore.state.accommodation = response.Accommodation;

                    self.props.store.state.quickBooking.ParkSelectionID = response.ParkID;
                    self.props.store.state.quickBooking.ParkSelectionName = response.ParkTitle;

                    //store the default values in cookie
                    try {
                        var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                        if (cookie == "") {
                            cookie = {};
                        }
                        else {
                            cookie = JSON.parse(cookie);
                        }
                        cookie["QuickBookingParkID"] = [response.ParkID];
                        cookie["QuickBookingParkName"] = [response.ParkTitle];
                        cookie["QuickBookingParkURL"] = [response.ParkUrl];
                        CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
                    }
                    catch (e) {
                    }
                },
                error: function (xhr, statusText, err) {
                }
            });
        },
        closeKeyBoard: function () {
            this.$nextTick(function () {
                if (document.activeElement == document.getElementById('quickSearch'))
                {
                    document.activeElement.blur();
                }


                this.updateSearchText();

            });
        },
        updateSearchText: function ()
        {
            var self = this;

            setTimeout(function () {
                var searchBar = document.getElementById("quickSearch");
                searchBar.value = self.props.store.state.quickBooking.ParkSelectionName;
            }, 650);
        }
    },
    mounted: function () {
        var self = this;

        if (self.isPark) {
            self.PrefillPark(PARK_DOCUMENT_ID);
        } 

        var cookie = CookieHelper.GetCookieValue(".BIG4_SAVED_SEARCHES");
        if (cookie != "") {
            cookie = JSON.parse(cookie);
            if (!!cookie.Searches) {
                this.recentlyViewed = cookie.Searches.reverse();
            }
        }

        cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");

        //Retrieves previously selected park from cookie
        if (cookie != "") {
            cookie = JSON.parse(cookie);

            //Do not retrieve search preferences for park if viewing on park page
            if (!self.isPark) {
                if (!!cookie.QuickBookingParkID && !!cookie.QuickBookingParkName && !!cookie.QuickBookingParkURL) {
                    this.SelectPark({ ParkID: cookie.QuickBookingParkID[0], title: cookie.QuickBookingParkName[0], url: cookie.QuickBookingParkURL[0] });
                }
            }

            if (!!cookie.Accommodation) {
                if (cookie.Accommodation == "Cabins") {
                    this.$nextTick(function () {
                        $("#Cabins").click();
                    });
                } else if (cookie.Accommodation == "Sites") {
                    this.$nextTick(function () {
                        $("#Sites").click();
                    });
                }
            }
        }

        $("#Sites").on('click', function () {
            //store the default values in cookie
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie["Accommodation"] = "Sites";
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }
        });

        $("#Cabins").on('click', function () {
            //store the default values in cookie
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie["Accommodation"] = "Cabins";
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }
        });


        $('#quickSearch').on('blur', function () {
            self.updateSearchText();
        });

    },
});;
Vue.component('quick-booking-accommodation-card', {
    props: ['item', 'accommodation-type', 'pms-data', 'details-button'],
    template: '#QuickBookingAccommodationCard',
    mixins: [MIXIN_MEMBERSHIP, Common],
    data: function () {
        return {
            state: window.AccommodationStore.state,
            bookingState: window.BookingStore.state,
            priceTotal: "0",
            discountedTotal: "0",
            CurrentPMSResult: [],
            PMSAvailable: true,
            unavailableReasons: [],
            currentOfferCode: 0,
        };
    },
    methods:
    {
        SelectCard: function (id) {
            window.BookingStore.state.quickBooking.PriceLoading = true;

            var accomCards = document.getElementsByClassName("c-card--quick-booking");
            for (var i = 0; i < accomCards.length; i++)
            {
                accomCards[i].className = accomCards[i].className.replace("is-selected", "");

                //Hide view details button
                if (!accomCards[i].parentElement.children[1].className.includes("d-none"))
                {
                    accomCards[i].parentElement.children[1].className += " d-none";
                }
            }

            if (this.$refs.AccommodationID.innerText == id) {
                //Show green highlight around card
                this.$refs.AccomCard.className += " is-selected";

                //Display view details button
                this.$refs.DetailsButton.className = this.$el.children[1].className.replace("d-none", "");
                this.$refs.DetailsLink.href = this.item.Url;

                window.BookingStore.state.quickBooking.AccommodationSelectionID = id;
                window.BookingStore.state.accommodationId = id;
            }

            window.BookingStore.UpdatePrice();
        },
        ProcessPMSResults: function (data) {
            var accom = this;
            var accommodationData = null;

            for (var i = 0; i < data.AllAccommodations.length; i++) {
                if (data.AllAccommodations[i].AccommodationID == this.item.AccommodationID) {
                    accommodationData = data.AllAccommodations[i].Allotment;
                }
            }
            accom.CurrentPMSResult = [];


            //now we need to select the best price
            if (accommodationData != null && accommodationData.length > 0) {
                var lowestIndex = 0;
                var lowestPrice = 100000;

                for (var i = 0; i < accommodationData.length; i++) {

                    accom.CurrentPMSResult.push(accommodationData[i]);
                    if (accommodationData[i].IsAvailable) {
                        if (accommodationData[i].Total < lowestPrice) {
                            lowestIndex = i;
                            lowestPrice = accommodationData[i].Total;
                        }
                    }
                }

                this.currentOfferCode = accommodationData[lowestIndex].Offercode;
                this.updatePrice();
            }
            else {
                this.state.accommodationLoading = false;
            }

        },
        updatePrice: function () {
            /*Update the displayed price to the cheapest, available price*/
            var pmsResult = this.CurrentPMSResult;
            var pmsResultIndex = 0;
            for (var i = 0; i < pmsResult.length; i++) {
                if (pmsResult[i].Offercode == this.currentOfferCode) {
                    pmsResultIndex = i;
                    this.priceTotal = this.RoundPrice(pmsResult[i].Total);
                    this.discountedTotal = this.RoundPrice(pmsResult[i].Total - pmsResult[i].MemberDiscount);
                    this.PMSAvailable = pmsResult[i].IsAvailable;
                }

                if (this.priceTotal != 0) {
                    this.state.accommodationLoading = false;
                }

                if (this.discountedTotal != 0) {
                    this.state.accommodationLoading = false;
                }
            }

            this.QuantityCheck(pmsResult, pmsResultIndex);
        },
        showMemberPrice: function () {
            return (this.isLoggedIn && !this.isHolidayPerksMember) || this.isMemberOnlyDeal;
        },
        memberPriceNotEqualToNonMember: function () {
            return !(this.DiscountedPrice == this.OriginalPrice);
        },
        memberIsVIPerks: function () {
            return (this.isLoggedIn && this.isVipPerksMember);
        },
        QuantityCheck: function (pmsResult, index) {

            var maxNumberOfRooms = 0;
            var index = 0;

            if (pmsResult != undefined) {
                //Checks that we only add the maximum number of available accommodations to the cart
                for (var i = 0; i < pmsResult[index].DailyAvailability.length - 1; i++) {
                    if (i == 0) {
                        maxNumberOfRooms = pmsResult[index].DailyAvailability[i].RoomsAvailable;
                    } else if (maxNumberOfRooms > pmsResult[index].DailyAvailability[i].RoomsAvailable) {
                        maxNumberOfRooms = pmsResult[index].DailyAvailability[i].RoomsAvailable;
                    }
                }

                window.AccommodationEventBus.$emit("quantity-update", { quantity: maxNumberOfRooms, accommodationID: this.item.AccommodationID });
            }
        },
    },
    computed: {
        DefaultDates: function () {
            return !this.CurrentPMSResult.length > 0;
        },
        OriginalPrice: function () {
            if (this.DefaultDates) {
                var self = this;
                //self.state.accommodationLoading = false;
                try {
                    if (this.item.AvailabilityCacheData) {
                        var total = this.priceTotal;
                        total = this.item.AvailabilityCacheData.DailyResults[0].Price;
                        var totalNum = total % 1; // find the price is decimal or not
                        if (totalNum == 0) {
                            return total; // whole number e.g: 5
                        }
                        else {
                            var roundedTotal = Math.round(total); // e.g 5.7 = 6, 5.1 = 5
                            return roundedTotal;
                        }
                    }
                } catch (err) {
                    return this.item.Price;
                }
            } else {
                return this.priceTotal;
            }
        },
        accommodationLoading: function () {
            var self = this;
            return self.state.accommodationLoading || self.state.callingPms;

        },
        DiscountedPrice: function () {
            if (this.DefaultDates) {
                var self = this;
                //self.state.accommodationLoading = false;
                try {
                    var total = this.discountedTotal;
                    if (this.item.AvailabilityCacheData) {
                        total = this.item.AvailabilityCacheData.DailyResults[0].DiscountPrice;

                        var totalNum = total % 1; // find the price is decimal or not
                        if (totalNum == 0) {
                            return total; // whole number e.g: 5
                        }
                        else {
                            var roundedTotal = Math.round(total); // e.g 5.7 = 6, 5.1 = 5
                            return roundedTotal;
                        }
                    }
                } catch (err) {
                    return this.item.DiscountPrice;
                }
            }
            return this.discountedTotal;
        },
        ItemNotAvailable: function () {
            var self = this;
            var validForPrice = false;
            var validForGuests = false;
            var validForDate = true;
            var validForPet = false;
            var validForType = true;
            var validFromPMS = self.PMSAvailable;

            //remove all the items
            this.unavailableReasons.splice(0);


            //Specific check for the quick booking widget 
            if (this.CurrentPMSResult.length > 0)
            {
                for (var i = 0; i < this.CurrentPMSResult.length; i++)
                {
                    if (this.CurrentPMSResult[i].IsAvailable == false && this.CurrentPMSResult[i].Offercode == this.currentOfferCode)
                    {

                        this.unavailableReasons.push({
                            priority: 1,
                            message: this.CurrentPMSResult[0].UnavailableMessage,
                        });

                        this.$el.parentElement.style.order = 2;
                        this.$nextTick(function () {
                            //checks if the number of unavailable badges matches the number of accom cards. If so, there is no possibile selection and we will display a message.
                            window.BookingStore.state.quickBooking.AllUnavailable = $('.c-card__badge--quick-booking').length == $('.quick-booking-card-col').length && $('.quick-booking-card-col').length != 0;
                        });
                        return true;
                    }
                }
            }

            var totalGuest = self.bookingState.adults + self.bookingState.children + self.bookingState.infants;

            //Pet Filter
            if (self.state.PetFriendly) {
                if (self.item.PetAllow) {
                    validForPet = true;
                }
                else {
                    this.unavailableReasons.push({
                        priority: 3,
                        message: 'No pets please'
                    });
                }
            }

            var withinPriceRange = (this.OriginalPrice / window.AccommodationStore.state.numberOfNights) >= self.state.MinPriceRange && (this.OriginalPrice / window.AccommodationStore.state.numberOfNights) <= self.state.MaxPriceRange;

            //Price Filter
            if (window.AccommodationStore.IsPriceFilterApplied()) {
                if (typeof this.OriginalPrice === 'undefined' || this.OriginalPrice === 0) {
                    validForPrice = true;
                }
                else if (withinPriceRange) {
                    validForPrice = true;
                }
                else {
                    this.unavailableReasons.push({
                        priority: 4,
                        message: 'Not within selected price range'
                    });
                }
            }
            else {
                validForPrice = true;
            }

            //Guest Filter
            if (self.item.Guest >= totalGuest) {
                validForGuests = true;
            }
            else {
                //if this is false, the PMS would have provided this message if applicable.
                if (validFromPMS) {
                    this.unavailableReasons.push({
                        priority: 2,
                        message: 'Exceeds max occupancy (' + self.item.Guest + ' guests)'
                    });
                }
            }

            //Date Filter 
            if (self.item.DateAvailable != undefined && window.DateFilterStore.state.dateFilterApplied == true) {
                validForDate = self.item.DateAvailable;
            }
            else if (window.DateFilterStore.state.dateFilterApplied) {
                validForDate = validFromPMS;
            }
            else {
                validFromPMS = true;
            }

            if (!validFromPMS) {

                var pmsResult = _.find(this.CurrentPMSResult, { Offercode: this.currentOfferCode });
                if (pmsResult !== null) {
                    this.unavailableReasons.push({
                        priority: 1,
                        message: pmsResult.UnavailableMessage
                    });
                }

            }

            if (self.state.PetFriendly) {
                if (validForPrice && validForPet && validForGuests && validForDate && validForType && validFromPMS) {
                    self.item.AvailableInFilter = true;
                } else {
                    self.item.AvailableInFilter = false;
                }
            }
            else {
                if (validForPrice && validForGuests && validForDate && validForType && validFromPMS) {
                    self.item.AvailableInFilter = true;
                } else {
                    self.item.AvailableInFilter = false;
                }
            }

            this.unavailableReasons = _.sortBy(this.unavailableReasons, ['priority']);

            this.$nextTick(function () {
                //availability check for pop up
                window.BookingStore.state.quickBooking.AllUnavailable = $('.c-card__badge--quick-booking').length == $('.quick-booking-card-col').length && $('.quick-booking-card-col').length != 0;
            });

            return !self.item.AvailableInFilter;
        },
    },
    mounted: function () {
        var self = this;

        window.AccommodationEventBus.$on('all-park-pms-availability-update', function (data) {
            self.ProcessPMSResults(data);
        });

        window.AccommodationEventBus.$on('date-filter-clear', function (data) {
            self.CurrentPMSResult = [];
            self.priceTotal = 0;
            self.discountedTotal = 0;
        });
    },
})

;
Vue.component('quick-booking-selection', {
    template: "#QUICK_BOOKING_SELECTION_TEMPLATE",
    data: function () {
        return {
            store: window.BookingStore,
            accommodationList: window.AccommodationStore.state.accommodations,
        }
    },
    computed: {
        props: function()
        {
            var self = this;
            return {
                SelectionValid: this.selectionValid,
                AccommodationSelected: this.accommodationSelected,
                AccommodationType: this.accommodationType,
                AccommodationList: this.accommodationList,
                AllUnavailable: this.allUnavailable,
                IsBooking: this.isBooking,
                ParkName: this.parkName,
                MaxRoomsExceeded: this.maxRoomsExceeded,
            };
        },
        isBooking: function ()
        {
            return this.store.state.addingToCart;
        },
        accommodationType: function ()
        {
            this.$data.store.state.quickBooking.AccommodationType;
        },
        isPark: function () {
            return this.store.state.quickBooking.isPark;
        },
        accommodationSelected: function ()
        {
            return this.$data.store.state.quickBooking.AccommodationSelectionID != "";
        },
        selectionValid: function ()
        {
            var self = this;
            var BookingState = window.BookingStore.state;

            if (BookingState.quickBooking.AccommodationType == "Site")
            {
                //Only bind these events if the elements are on screen
                $('.c-select__input').on('click', function () {
                    self.hideEquipmentValidation();
                });

                $('#width').on('click', function (e) {
                    self.hideWidthValidation();
                });

                $('#length').on('click', function () {
                    self.hideLengthValidation();
                });

                return (BookingState.quickBooking.AccommodationType != "" && BookingState.quickBooking.ParkSelectionName != ""
                    && BookingState.startDate != null && BookingState.endDate != null
                    && BookingState.equipment.EquipmentTypeID != null && BookingState.equipment.Width != null && BookingState.equipment.Length != null);
            }

            return (BookingState.quickBooking.AccommodationType != "" && BookingState.quickBooking.ParkSelectionName != ""
                && BookingState.startDate != null && BookingState.endDate != null);
        },
        allUnavailable: function () {
            //If the number of unavailable badges matches the number of accom cards
            return this.$data.store.state.quickBooking.AllUnavailable;
        },
        maxRoomsExceeded: function ()
        {
            return this.store.state.showMaxAccommodationError;
        }
    },
    methods: {
        datesFailedValidation: function () {
            if ($('#check_in_date_parsed').val() == "") {
                return true;
            } else return false;
        },
        equipmentFailedValidation: function () {
            if ($('#equipment').val() == null) {
                return true;
            } else return false;
        },
        widthFailedValidation: function () {
            if ($('#width').val() == undefined) {
                return true;
            } else {
                return false;
            }
        },
        lengthFailedValidation: function () {
            if ($('#length').val() == undefined) {
                return true;
            } else {
                return false;
            }
        },
        showValidation: function () {
            if (this.store.state.noTariffsAvailable) {
                $('.no-tariffs-available').addClass('has-error');
                //scroll to the invalid element
                $('html, body').animate({
                    scrollTop: $(".has-error").offset().top - 200
                }, 1000);

                return;
            }

            //If the park selection is invalid
            var searchBar = document.getElementById("quickSearch");

            //If there is no searchBar we are on a park page. Skip validation
            if (searchBar != null)
            {
                if (searchBar.value == "" || (searchBar.value != this.store.state.quickBooking.ParkSelectionName))
                {
                    searchBar.className += " has-error";
                    $('.c-booking-location-error').css('opacity', '100');
                }
            }

            //If no accommodation type is selected
            if (this.store.state.quickBooking.AccommodationType == "")
            {
                $('.c-booking-type-error').css('opacity', '100');
                $('.c-radio-accommodation__placeholder').addClass("has-error");
            }

            //When the user clicks add to cart with no dates selected.
            if (this.datesFailedValidation()) {
                $('.c-input-date').addClass('has-error');
                $('.c-booking-date-error').css('opacity', '100');
            }

            //When the user clicks add to cart with no equipment selected.
            if (this.equipmentFailedValidation()) {
                $('.c-select ').addClass('has-error');
                $('.c-booking-equipment-error').css('opacity', '100');
            }

            //When the user clicks add to cart with no equipment length selected.
            if (this.lengthFailedValidation()) {
                $('#length').closest('.c-field').addClass('has-error');
                $('.c-booking-equipment-size-error').css('opacity', '100');
            }

            //When the user clicks add to cart with no equipment width selected.
            if (this.widthFailedValidation()) {
                $('#width').closest('.c-field').addClass('has-error');
                $('.c-booking-equipment-size-error').css('opacity', '100');
            }



        },
        hideDateValidation: function () {
            $('.c-input-date').removeClass('has-error');
            $('.c-booking-date-error').css('opacity', 0);
        },
        hideEquipmentValidation: function () {
            $('.c-select ').removeClass('has-error');
            $('.c-booking-equipment-error').css('opacity', 0);
        },
        hideWidthValidation: function () {
            $('#width').closest('.c-field').removeClass('has-error');
            $('#width').removeClass('has-error');
            $('.c-booking-equipment-size-error').css('opacity', 0);
        },
        hideLengthValidation: function () {
            $('#length').closest('.c-field').removeClass('has-error');
            $('#length').removeClass('has-error');
            $('.c-booking-equipment-size-error').css('opacity', 0);
        },
        hideSearchBarValidation: function ()
        {
            $('.c-booking-location-error').css('opacity', '0');
            var searchBar = document.getElementById("quickSearch").className = document.getElementById("quickSearch").className.replace("has-error", "");
        },
        hideTypeValidation: function ()
        {
            $('.c-booking-type-error').css('opacity', '0');
            $('.c-radio-accommodation__placeholder').removeClass('has-error');
        },
    },
    created: function () {
    },
    mounted: function ()
    {
        var self = this;

        //If the user opens the date picker we want to remove validation errors
        $('.c-input-date').on('click', function () {
            self.hideDateValidation();
        });

        $('#quickSearch').on('click', function () {
            self.hideSearchBarValidation();
        });

        $('#Cabins').on('click', function () {
            self.hideTypeValidation();
        });

        $('#Sites').on('click', function () {
            self.hideTypeValidation();
        });

        window.AccommodationEventBus.$on("accommodations-loaded", function () {
            self.accommodationList = window.AccommodationStore.state.accommodations;
        });
    },

});;
Vue.component('quick-booking-selection-data-wrapper', {
    props: ["accommodation-list"],
    data: function () {
        return {
            state: window.BookingStore.state,
        }
    },
    computed: {
        accommodationType: function () {
            return this.state.quickBooking.AccommodationType;
        },
        parkName: function () {
            return this.state.quickBooking.ParkSelectionName;
        },
        isLoading: function()
        {
            return this.state.quickBooking.PriceLoading || this.state.addingToCart;
        },
    },
    mounted: function ()
    {
        var self = this;

        this.$nextTick(function () {
            window.AccommodationEventBus.$emit("quick-booking-date-changed", { start: this.state.startDate, end: this.state.endDate });
        });

        $('#quickBookSelectionBackButton').on('click', function () {
            self.state.quickBooking.AccommodationSelectionID = "";
            self.state.quickBooking.CurrentAllotmentSelection = {};
            self.state.accommodationId = null;
        });


        //Closes both open modals when 'close' button is selected
        $('#quickBookingSelectionCloseButton').on('click', function () {
            self.state.quickBooking.AccommodationSelectionID = "";
            self.state.quickBooking.CurrentAllotmentSelection = {};
            self.state.accommodationId = null;
            setTimeout(function () {
                $("#quickBookingCloseButton").click();
            }, 200);
        });

        //Closes both open modals when clicking outside of modal
        $('.c-selection-modal__overlay').on('click', function () {
            self.state.quickBooking.AccommodationSelectionID = "";
            self.state.quickBooking.CurrentAllotmentSelection = {};
            self.state.accommodationId = null;
            setTimeout(function () {
                $("#quickBookingCloseButton").click();
            }, 200);
        });
    },

});;
Vue.component('quick-booking-widget-price-display', {
    template: "#QuickBookingWidgetPriceDisplayTemplate",
    mixins: [MIXIN_BOOKING_WIDGET, MIXIN_MEMBERSHIP],
    props:["availability-cache-data", "is-quick-booking"],
    data: function () {
        return {
            store: window.BookingStore,
        }
    },
    computed: {
        allotment: function ()
        {
            return window.BookingStore.state.quickBooking.CurrentAllotmentSelection;
        },
        price: function () {
            if (!this.isTotalPrice && !this.isQuickBooking) {
                //this returns the first price as it should be returning "tonights" price
                return this.RoundPrice(this.store.GetCurrentAccommodation().AvailabilityCacheData.DefaultRate.Price);

            }
            else {
                if (this.allotment != undefined)
                {
                    if (isNaN(this.RoundPrice(this.allotment.Total))) {
                        return ""
                    }

                    this.$nextTick(function () {
                        window.BookingStore.state.canAddToCart = true;
                        window.BookingStore.state.quickBooking.PriceLoading = false;
                    });
                    return this.RoundPrice(this.allotment.Total);
                }
            }
            
        },
        priceIsLoading: function ()
        {
            return window.BookingStore.state.quickBooking.PriceLoading;
        },
        dynamicSummaryString: function ()
        {
            if (this.store.state.startDate && this.store.state.endDate)
            {
                var a = moment(this.store.state.startDate._d);
                var b = moment(this.store.state.endDate._d);

                var children = this.store.state.children > 0 ? ", " + this.store.state.children + " children" : "";
                if (this.store.state.children == 1)
                {
                    children = children.replace("children", "child");
                }

                var infants = this.store.state.infants > 0 ? ", " + this.store.state.infants + " infants" : "";
                if (this.store.state.infants == 1) {
                    infants = infants.replace("infants", "infant");
                }

                var adults = this.store.state.adults == 1 ? this.store.state.adults + " adult" : this.store.state.adults + " adults";

                var nights = (b.diff(a, 'days'));

                var nightMessage = nights + " nights - ";

                if (nights == 1)
                {
                    nightMessage = nightMessage.replace("nights", "night");
                }

                return nightMessage + adults + children + infants; 
            } 
            return '';
        },
        discountPrice: function () {
            if (!this.isTotalPrice && !this.isQuickBooking) {
                //this returns the first price as it should be returning "tonights" price
                return this.RoundPrice(this.store.GetCurrentAccommodation().AvailabilityCacheData.DefaultRate.DiscountPrice);
            }
            else {
                if (this.allotment != undefined)
                {
                    if (isNaN(this.RoundPrice(this.allotment.Total))) {
                        return ""
                    }

                    this.$nextTick(function () {
                        window.BookingStore.state.canAddToCart = true;
                        window.BookingStore.state.quickBooking.PriceLoading = false;
                    });
                    return this.RoundPrice(this.allotment.Total - this.allotment.MemberDiscount);
                }
            }
        },
        discountAmount: function () {
            return this.RoundDiscountPrice(this.allotment.Discount);
        },
        isDeal: function () {
            return this.isTotalPrice && this.allotment.IsSpecialRate;
        },
        isTotalPrice: function () {
            return !!this.allotment;
        },
        
        isMemberOnlyDeal: function () {
            //all deals are member only deals...
            return this.isDeal;
        },
        showMemberPrice: function () {
            return (this.isLoggedIn && !this.isHolidayPerksMember) || this.isMemberOnlyDeal;
        },
        memberPriceEqualToNonMember: function ()
        {
            return (this.discountPrice == this.price);
        },
    
        state: function () {
            return this.store.state;
        },
        
        membershipLevelClass: function () {
            if (this.isDeal) {
                if (this.allotment.MemberOnly) {
                    if (this.isVipPerksMember) { 
                        return "c-pricing__membership--vip";
                    }
                    return "c-pricing__membership--plus"; 
                }
                else {
                    return "c-pricing__membership--holiday"; 
                }
            }

            if (this.isVipPerksMember) {
                return "c-pricing__membership--vip";
            }
            return "c-pricing__membership--plus"; 
        },
        membershipLevelLogo: function () {

            if (this.isDeal) {
                if (this.allotment.MemberOnly) {
                    if (this.isVipPerksMember) {
                        return this.logos.vipPerks;
                    }
                    return this.logos.perksPlus;
                }
                else {
                    return this.logos.holidayPerks;
                }
            }

            if (this.isVipPerksMember) {
                return this.logos.vipPerks;
            }
            return this.logos.perksPlus; 

        },
        mounted: function ()
        {
        }
    },
});
;
Vue.component('accommodation-filter', {

    /*
     * Initial state of the component's data.
     */
    props: ['store-name', 'apply-filter-function-name', 'items'],

    data: function () {
        return {
            //items:['item1','item2']
        }
    },
    methods: {
        toggle: function () {
            this.$parent.toggle();
        },
        close: function () {
            this.$parent.close();
        },
        applyFilter: function () {
            window[this.storeName][this.applyFilterFunctionName]();
            this.toggle();

            var self = this;
            this.$nextTick(function () {
                self.$forceUpdate();
            });
        },
        active: function () {
            var values = this.store.categories.values;

            if (Object.entries(values).length > 0) {
                for (var i = 0; i < Object.entries(values).length; i++) {
                    if (Object.entries(values)[i][1] == true) {
                        return true;
                    }
                }
            } else {
                return false;
            }
        },
        clear: function () {
            this.store.categories.values = {};
            this.store.categories.tempValues = {};
            this.toggle();
            window[this.storeName][this.applyFilterFunctionName]();
            this.$nextTick(function () {
                self.$forceUpdate();
            });
        }
    },
    computed: {
        store: function () {
            return window[this.storeName].state;
        },
        visible: function () {
            return this.$parent.visible;
        },
    }

});



window.AccommodationFilterStore = {
    state: [],
    default: ["Cabins"],

    subscribeFilter: function (cookieValue) {

        var data = this.default;

        //see if we have a cookie to retrieve dates from
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie != "") {

                cookie = JSON.parse(cookie);
                if (!!cookie[cookieValue]) {
                    data = cookie[cookieValue];
                }
            }
        } catch (e) {
        }

        this.state.push({
            id: this.state.length,
            data: data
        });

        return this.state.length - 1;
    },
    applyFilter: function (id, data, cookieValue) {
        if (this.state[id].data != data) {
            //when we apply the filter, we want to store the data in a cookie
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie[cookieValue] = data;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }

            this.state[id].data = data;
        }
    },
    setDefault: function (id) {
        this.state[id].data = this.default;
    },
    prefillSelections: function () {
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie != "") {
                cookie = JSON.parse(cookie);

                if (!!cookie.Dates) {
                    this.state.startDate = moment(cookie.Dates.start);
                    this.state.endDate = moment(cookie.Dates.end);

                    this.state.dataPrefilled = true;
                }

                if (!!cookie.Guests) {
                    this.state.adults = cookie.Guests.adults;
                    this.state.children = cookie.Guests.children;
                    this.state.infants = cookie.Guests.infants;

                    //For quick booking, make sure we update the accommodation store values
                    if (window.AccommodationStore != undefined) {
                        window.AccommodationStore.state.NumAdults = cookie.Guests.adults;
                        window.AccommodationStore.state.NumChildren = cookie.Guests.children;
                        window.AccommodationStore.state.NumInfants = cookie.Guests.infants;
                    }

                    this.state.dataPrefilled = true;
                }
            }
        } catch (ex) {
            console.log('Error occured retrieving Search Preferences cookie');
        }
    },
};

Vue.component('accommodation-toggle-filter-component', {
    props: ['event-bus', 'update-event', 'items', 'cookie-value'],
    data: function () {
        return {
            store: window.AccommodationFilterStore,
            id: null,
            isOpen: false,
            scrollPos: 0,
        }
    },
    methods: {
        toggle: function () {
            this.isOpen = !this.isOpen;
            this.$parent.toggle();

            if (this.isOpen) {

                //Disable mobile scrolling when open
                if (this.$mq == 'sm') {
                    this.$data.scrollPos = window.scrollY;
                }

                for (var j = 0; j < this.$refs.toggle.length; j++) {
                    this.$refs.toggle[j].checked = false;
                }

                for (var i = 0; i < this.state.data.length; i++) {
                    for (var j = 0; j < this.$refs.toggle.length; j++) {
                        if (this.state.data[i] == this.$refs.toggle[j].value) {
                            this.$refs.toggle[j].checked = true;
                        }
                    }
                }
            }

            window[this.eventBus].$emit('filter-toggle-event', this.$el);
        },
        close: function () {
            this.applyFilter();
            this.$refs.toggle.checked = this.state.data.isOn;
            this.$parent.close();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
        },
        applyFilter: function () {

            var data = [];
            for (var i = 0; i < this.$refs.toggle.length; i++) {
                if (this.$refs.toggle[i].checked) {
                    data.push(this.$refs.toggle[i].value);
                }
            }

            this.store.applyFilter(this.id, data, this.cookieValue);
            this.toggle();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
            window[this.eventBus].$emit(this.updateEvent, data);

        },
        applyOnFilterChange: function () {

            var data = [];
            for (var i = 0; i < this.$refs.toggle.length; i++) {
                if (this.$refs.toggle[i].checked) {
                    data.push(this.$refs.toggle[i].value);
                }
            }

            this.store.applyFilter(this.id, data, this.cookieValue);
            window[this.eventBus].$emit(this.updateEvent, data);

        },
        clear: function () {
            this.store.setDefault(this.id);

            for (var i = 0; i < this.$refs.toggle.length; i++) {
                if (this.$refs.toggle[i].checked) {
                    this.$refs.toggle[i].checked = false;
                }
            }

            var data = this.state.data;


            //store the default values in cookie
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie[this.cookieValue] = data;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }
            window[this.eventBus].$emit(this.updateEvent, data);
        },
        updateValues: function () {
            var data = [];
            for (var i = 0; i < this.$refs.toggle.length; i++) {
                if (this.$refs.toggle[i].checked) {
                    data.push(this.$refs.toggle[i].value);
                }
            }

            this.state.data = data;
        }
    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        dynamicButtonAccommodationFilterString: function () {
            var result = '';
            if (this.state && this.state.data) {
                if (this.state.data == "Sites") {
                    this.state.data = ["Sites"]
                } else if (this.state.data == "Cabins") {
                    this.state.data = ["Cabins"]
                }
                if (this.state.data.length > 0) {
                    result = this.state.data.length > 1 ? this.state.data[0] + " + " + (this.state.data.length - 1) + " more" : this.state.data[0];
                    if (this.state.data.length == 2) {
                        result = this.state.data[0] + " + " + this.state.data[1];
                    }
                }
            }
            return result;
        },
        visible: function () {
            return this.$parent.visible;
        },
        isActive: function () {
            if (this.state && this.state.data) {

                if (this.isOpen) {
                    return true;
                }
                return this.state.data.length > 0;
            }
            return false;
        }
    },
    mounted: function () {
        var self = this;

        this.store.prefillSelections();

        this.id = window.AccommodationFilterStore.subscribeFilter(this.cookieValue);
        this.$nextTick(function () {
            if (this.state.data != this.store.default) {
                window[this.eventBus].$emit(this.updateEvent, this.state.data);
            }
        });

        //Make sure we set ourself to closed when another filter is clicked
        window[this.eventBus].$on('filter-toggle-event', function (data) {
            if (data != self.$el && self.isOpen) {
                self.applyOnFilterChange();
                self.state.data = self.state.data;
                self.isOpen = false;
            }
        });
    }

});




;
Vue.component('accommodation-toggle', {

    /*
     * Initial state of the component's data.
     */
    props: ['store-name', 'apply-filter-function-name', 'items'],

    data: function () {
        return {
            //items:['item1','item2']
        }
    },
    methods: {
        applyFilter: function () {
            window[this.storeName][this.applyFilterFunctionName]();

            var self = this;
            this.$nextTick(function () {
                self.$forceUpdate();
            });
        },
        active: function () {
            var values = this.store.categories.values;

            if (Object.entries(values).length > 0) {
                for (var i = 0; i < Object.entries(values).length; i++)
                {
                    if (Object.entries(values)[i][1] == true)
                    {
                        return true;
                    }
                }
            } else {
                return false;
            }
        },
        clear: function () {
            this.store.categories.values = {};
            this.store.categories.tempValues = {};
            window[this.storeName][this.applyFilterFunctionName]();
            this.$nextTick(function () {
                self.$forceUpdate();
            });
        }
    },
    computed: {
        store: function () {
            return window[this.storeName].state;
        },
        visible: function () {
            return this.$parent.visible;
        },
    }

});

Vue.component('accommodation-toggle-component', {
    props: ['event-bus', 'update-event', 'items', 'cookie-value'],
    data: function () {
        return {
            store: window.AccommodationFilterStore,
            id: null,
            scrollPos: 0,
        }
    },
    methods: {
        applyFilter: function (data) {

            
            this.store.applyFilter(0, data, "Accommodation");

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
            window[this.eventBus].$emit(this.updateEvent, data);

        },
    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        visible: function () {
            return this.$parent.visible;
        },
        isActiveCabins: function () {
            if (this.store.state && this.store.state[0].data) {
                return this.store.state[0].data.length > 0 && this.store.state[0].data[0] == "Cabins";
            }
            return false;
        },
        isActiveSites: function () {
            if (this.store.state && this.store.state[0].data) {
                return this.store.state[0].data.length > 0 && this.store.state[0].data[0] == "Sites";
            }
            return false;
        }
    },
    mounted: function () {
  
    }

});




;
Vue.component('checkbox-filter', {

    /*
     * Initial state of the component's data.
     */
    props: ['store-name', 'apply-filter-function-name', 'items'],

    data: function () {
        return {
            //items:['item1','item2']
        }
    },
    methods: {
        toggle: function () {
            this.$parent.toggle();
        },
        close: function () {
            this.$parent.close();
        },
        applyFilter: function () {
            window[this.storeName][this.applyFilterFunctionName]();
            this.toggle();

            var self = this;
            this.$nextTick(function () {
                self.$forceUpdate();
            });
        },
        active: function () {
            var values = this.store.categories.values;

            if (Object.entries(values).length > 0) {
                for (var i = 0; i < Object.entries(values).length; i++)
                {
                    if (Object.entries(values)[i][1] == true)
                    {
                        return true;
                    }
                }
            } else {
                return false;
            }
        },
        clear: function () {
            this.store.categories.values = {};
            this.store.categories.tempValues = {};
            this.toggle();
            window[this.storeName][this.applyFilterFunctionName]();
            this.$nextTick(function () {
                self.$forceUpdate();
            });
        }
    },
    computed: {
        store: function () {
            return window[this.storeName].state;
        },
        visible: function () {
            return this.$parent.visible;
        },
    }

});



window.CheckboxFilterStore = {
    state: [],
    default: [],

    subscribeFilter: function (cookieValue) {

        var data = this.default;

        //see if we have a cookie to retrieve dates from
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie != "") {

                cookie = JSON.parse(cookie);

                if (cookie[cookieValue].length > 0) {
                    cookie[cookieValue].filter(function (x) { return x !== null && x !== undefined });
                }

                if (!!cookie[cookieValue]) {
                    data = cookie[cookieValue];
                }
            }
        } catch (e) {
        }

        this.state.push({
            id: this.state.length,
            data: data
        });

        return this.state.length - 1;
    },
    applyFilter: function (id, data, cookieValue) {
        if (this.state[id].data != data)
        {
            //when we apply the filter, we want to store the data in a cookie
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }

                cookie[cookieValue] = data;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }

            this.state[id].data = data;
        }
    },
    setDefault:function(id) {
        this.state[id].data = this.default;
    },
};

Vue.component('checkbox-filter-component', {
    props: ['event-bus', 'update-event', 'items', 'cookie-value', 'default-values'],
    data: function () {
        return {
            store: window.CheckboxFilterStore,
            id: null,
            isOpen: false,
            scrollPos: 0,
        }
    },
    methods: {
        toggle: function () {
            this.isOpen = !this.isOpen;
            this.$parent.toggle();

            if (this.isOpen) {

                //Disable mobile scrolling when open
                if (this.$mq == 'sm') {
                    this.$data.scrollPos = window.scrollY;
                }

                for (var j = 0; j < this.$refs.toggle.length; j++) {
                    this.$refs.toggle[j].checked = false;
                }

                for (var i = 0; i < this.state.data.length; i++) {
                    for (var j = 0; j < this.$refs.toggle.length; j++) {
                        if (this.state.data[i] == this.$refs.toggle[j].value) {
                            this.$refs.toggle[j].checked = true;
                        }
                    }
                }
            }

            window[this.eventBus].$emit('filter-toggle-event', this.$el);
        },
        close: function () {
            this.applyFilter();
            this.$refs.toggle.checked = this.state.data.isOn;
            this.$parent.close();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
        },
        applyFilter: function () {

            var data = [];
            for (var i = 0; i < this.$refs.toggle.length; i++) {
                if (this.$refs.toggle[i].checked) {
                    data.push(this.$refs.toggle[i].value);
                }
            }
            
            this.store.applyFilter(this.id, data, this.cookieValue);
            this.toggle();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
            window[this.eventBus].$emit(this.updateEvent, data);

        },
        applyOnFilterChange: function () {

            var data = [];
            for (var i = 0; i < this.$refs.toggle.length; i++) {
                if (this.$refs.toggle[i].checked) {
                    data.push(this.$refs.toggle[i].value);
                }
            }

            this.store.applyFilter(this.id, data, this.cookieValue);
            window[this.eventBus].$emit(this.updateEvent, data);

        },
        clear: function () {
            this.store.setDefault(this.id);

            for (var i = 0; i < this.$refs.toggle.length; i++) {
                if (this.$refs.toggle[i].checked) {
                    this.$refs.toggle[i].checked = false;
                }
            }

            var data = this.state.data;


            //store the default values in cookie
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie[this.cookieValue] = data;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }
     
            window[this.eventBus].$emit(this.updateEvent, data);
        },
        updateValues: function ()
        {
            var data = [];
            for (var i = 0; i < this.$refs.toggle.length; i++) {
                if (this.$refs.toggle[i].checked) {
                    data.push(this.$refs.toggle[i].value);
                }
            }

            this.state.data = data;
        }
    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        dynamicButtonCheckBoxString: function ()
        {
            var result = '';
            if (this.state && this.state.data) {
                if (this.state.data.length > 0) {
                    result = this.state.data.length > 1 ? this.state.data[0] + " + " + (this.state.data.length - 1) + " more" : this.state.data[0];
                    if (this.state.data.length == 2)
                    {
                       result = this.state.data[0] + " + " + this.state.data[1];
                    }
                }
            }
            return result;
        },
        visible: function () {
            return this.$parent.visible;
        },
        isActive: function () {
            if (this.state && this.state.data) {

                if(this.isOpen) {
                    return true;
                }
                return this.state.data.length > 0;
            }
            return false;
        }
    },
    mounted: function () {
        var self = this;

        this.id = window.CheckboxFilterStore.subscribeFilter(this.cookieValue);
        this.$nextTick(function () {
            if (this.state.data != this.store.default) {
                this.state.data = this.state.data.filter(function (x) { return x !== null && x !== undefined });
                window[this.eventBus].$emit(this.updateEvent, this.state.data);
            }
        });

        if (this.defaultValues && this.defaultValues.length > 0) {
            self.state.data = this.defaultValues;
        }

        //Make sure we set ourself to closed when another filter is clicked
        window[this.eventBus].$on('filter-toggle-event', function (data) {
            if (data != self.$el && self.isOpen) {
                self.applyOnFilterChange();
                self.state.data = self.state.data;
                self.isOpen = false;
            }
        });
    }

});




;
window.DateFilterStore = {
    state: [
        {
            dateFilterApplied: false,
            previousDateRange: {
                start: moment().toDate(),
                end: moment().add(1, 'day').toDate()
            },
            adjustmentDate: null,
            adjustedStart: false,
            adjustedEnd: false,
            selectedRange: false,
            disabledHighlightDates: null,
        }
    ],
    default: {
        start: moment().toDate(),
        end: moment().add(1, 'day').toDate()
    },

    subscribeFilter: function () {
        var defaultDate = {
            start: moment(this.state[0].previousDateRange.start).toDate(),
            end: moment(this.state[0].previousDateRange.end).toDate()
        }

        //see if we have a cookie to retrieve dates from
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie != "") {

                cookie = JSON.parse(cookie);
                if (!!cookie.Dates && cookie.Dates.start != null && cookie.Dates.end != null) {
                    //Ignore cookie values if they are in the past
                    if (moment(cookie.Dates.end).toDate() > moment().toDate() && moment(cookie.Dates.start).toDate() >= moment().startOf('day').toDate()) {
                        defaultDate.start = moment(cookie.Dates.start).toDate();
                        defaultDate.end = moment(cookie.Dates.end).toDate();
                        window.DateFilterStore.state.rangeSelected = true;
                    }
                }
            }
        }
        catch (e) {
        }


        this.state.push({
            id: this.state.length,
            data: defaultDate
        });

        return this.state.length - 1;
    },
    applyFilter: function (id, data) {
        this.state[id].data = data;
        //when we apply the filter, we want to store the data in a cookie
        try {

            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }

            cookie.Dates = data;
            this.state[id].previousDateRange = data;
            CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
        } catch (e) {
        }
    },
    setDefault: function (id) {

        var defaultDate =
        {
            start: moment(this.state[0].previousDateRange.start).toDate(),
            end: moment(this.state[0].previousDateRange.end).toDate()
        }
        this.state[id].data = defaultDate;
    },
};

Vue.component('date-filter-component', {
    props: ['event-bus', 'update-event', 'default-start-date', 'default-end-date'],
    data: function () {
        return {
            store: window.DateFilterStore,
            id: null,
            isOpen: false,
            errorOpacity: 0,
            maxNightsError: false,
            scrollPos: 0,
        }
    },
    methods: {
        toggle: function () {
            this.isOpen = !this.isOpen;
            this.$parent.toggle();
            if (this.isOpen) {
                //Disable mobile scrolling when open
                if (this.$mq == 'sm') {
                    this.$data.scrollPos = window.scrollY;
                }
                var month = moment(this.state.data.start).format('M'); // get the selected start date and its month
                var year = moment(this.state.data.start).format('YYYY'); // get the selected start date and its year
                this.$refs.dateFilter.selectedDate = this.state.data; // selected date range

                window['VcalendarMobileEventBus'].$emit('month-change');
            } else {
                this.$nextTick(function () {
                    document.getElementsByTagName('body')[0].style.position = 'unset';
                });
                document.body.style.top = '';
            }
            this.toggleStyling();

            window[this.eventBus].$emit('filter-toggle-event', this.$el);
        },
        DateFilterApplied: function () {
            if (this.defaultStartDate && this.defaultEndDate) {
                return this.store.state.dateFilterApplied;
            }

            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie != "") {

                    cookie = JSON.parse(cookie);

                    if (!!cookie.Dates) {
                        this.store.state.dateFilterApplied = true;
                        this.updateNights();
                        return true;
                    } else if (this.state.previousDateRange) {
                        this.store.state.dateFilterApplied = true;
                        this.updateNights();
                        return true;
                    }
                    this.store.state.dateFilterApplied = false;
                    return false;
                }
                return true;
            }
            catch (e) {
                return true;
            }
        },
        isActive: function () {
            return this.DateFilterApplied() || this.isOpen;
        },
        close: function () {
            if (!this.isDefault ) {
                this.$parent.close();
                this.applyFilter();
            } else {
                this.$parent.close();
                this.isOpen = false;
            }

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
        },
        updateNights: function (clear) {
            //If this filter is on the accommodation page, track nights for park card price filtering
            if (window.AccommodationStore != undefined) {

                if (clear) {
                    window.AccommodationStore.state.numberOfNights = 1;
                } else {
                    //Calculate number of nights staying for selection
                    var a = moment(this.state.data.start);
                    var b = moment(this.state.data.end);

                    if (this.$refs.dateFilter.selectedDate != null) {
                        a = moment(this.$refs.dateFilter.selectedDate.start);
                        b = moment(this.$refs.dateFilter.selectedDate.end);
                    }

                    window.AccommodationStore.state.numberOfNights = (a.diff(b, 'days')) * -1;
                }
            } else if (window.SearchResultsAndFiltersWidgetStore != undefined) {
                if (clear) {
                    window.SearchResultsAndFiltersWidgetStore.state.numberOfNights = 1;
                } else {
                    //Calculate number of nights staying for selection
                    var a = moment(this.state.data.start);
                    var b = moment(this.state.data.end);

                    if (this.$refs.dateFilter.selectedDate != null) {
                        a = moment(this.$refs.dateFilter.selectedDate.start);
                        b = moment(this.$refs.dateFilter.selectedDate.end);
                    }

                    window.SearchResultsAndFiltersWidgetStore.state.numberOfNights = (a.diff(b, 'days')) * -1;
                }
            }
        },
        applyFilter: function () {
            var incompleteSelection = false;

                this.store.applyFilter(this.id, this.$refs.dateFilter.selectedDate);
                this.toggle();
                this.isOpen = false;

                this.updateNights();

                if (!(this.state.data.start != null && this.state.data.end != null)) {
                    this.state.data.end = moment(this.state.data.start).add(1, 'days')._d
                    incompleteSelection = true;
                }

                //re-enable mobile scrolling, return scrolling position to previous state
                if (this.$mq == 'sm') {
                    document.getElementsByTagName('body')[0].style.position = '';
                    window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
                }

                //If the datepicker was closed during an incomplete selection (start date selected but no end date),
                //we want to disable range selection and display the 
                if (incompleteSelection) {
                    this.store.applyFilter(this.id, this.$refs.dateFilter.selectedDate);
                    this.disableRangeSelect();
                }

                //TW: Check for accommodation filter vs search filter
                if (this.$refs.ParkID != null) {
                    this.state.data["ParkID"] = parseInt(this.$refs.ParkID.innerText);
                    window[this.eventBus].$emit(this.updateEvent, this.state.data);
                } else {
                    window[this.eventBus].$emit(this.updateEvent, this.state.data);
                }
        },
        applyOnFilterChange: function () {
            if (!this.isDefault ) {
                var incompleteSelection = false;

                this.store.applyFilter(this.id, this.$refs.dateFilter.selectedDate);

                if (!(this.state.data.start != null && this.state.data.end != null)) {
                    this.state.data.end = moment(this.state.data.start).add(1, 'days')._d
                    incompleteSelection = true;
                }

                //TW: Check for accommodation filter vs search filter
                if (this.$refs.ParkID != null) {
                    this.state.data["ParkID"] = parseInt(this.$refs.ParkID.innerText);
                    window[this.eventBus].$emit(this.updateEvent, this.state.data);
                } else {
                    window[this.eventBus].$emit(this.updateEvent, this.state.data);
                }

                //If the datepicker was closed during an incomplete selection (start date selected but no end date),
                //we want to disable range selection and display the 
                if (incompleteSelection) {
                    this.disableRangeSelect();
                }
            }
        },
        toggleStyling: function () {
            var self = this;
            //If we have default dates and no applied filter we do not show any dates as selected
            this.$nextTick(function () {
                if (this.isDefault && !this.DateFilterApplied() && self.store.state.adjustmentDate == undefined) {
                    this.$refs.dateFilter.$refs.datePicker.value = null;
                    this.$refs.dateFilter.selectedDate = null;
                }
            });
        },
        disableRangeSelect: function () {
            var self = this;
            self.$nextTick(function () {
                var datePicker = self.$refs.dateFilter.$refs.datePicker;
                if (datePicker.dragValue != null) {
                    //Prevent calendar from entering range selection
                    datePicker.$children[0].dragValue = null;
                    datePicker.$children[0].value.start = self.state.data.start;
                    datePicker.$children[0].value.end = self.state.data.end;
                    self.$refs.dateFilter.isDragging = false;
                }
                self.toggleStyling();
            });
        },
        enableRangeSelect: function () {
            //This disregards the end date of a selected range and re-starts the range selection functionality
            var self = this;
            var datePicker = self.$refs.dateFilter.$refs.datePicker;
            var dateFilter = self.$refs.dateFilter;

            if (dateFilter.selectedDate && this.store.state.adjustmentDate) {
                if (dateFilter.selectedDate.start.toDateString() == this.store.state.adjustmentDate.toDateString()) {
                    datePicker.$children[0].dragValue = { start: dateFilter.selectedDate.start, end: moment(dateFilter.selectedDate.start).add(1, 'days')._d };
                    datePicker.$children[0].value.start = dateFilter.selectedDate.start;
                    datePicker.$children[0].value.end = null;
                }
                else if (dateFilter.selectedDate.end.toDateString() == this.store.state.adjustmentDate.toDateString()) {
                    datePicker.$children[0].dragValue = { start: dateFilter.selectedDate.end, end: moment(dateFilter.selectedDate.end).add(1, 'days')._d };
                    datePicker.$children[0].value.start = dateFilter.selectedDate.end;
                    datePicker.$children[0].value.end = null;
                }
                self.$refs.dateFilter.isDragging = true;
                window.DateFilterStore.state.rangeSelected = false;
            }
        },
        adjustStart: function (selectionEnd, adjustmentDate) {
            var self = this;
            self.clear();
            self.$refs.dateFilter.selectedDate.start = adjustmentDate;
            self.$refs.dateFilter.selectedDate.end = selectionEnd;
            window.DateFilterStore.state.rangeSelected = true;
        },
        adjustEnd: function (selectionStart, adjustmentDate) {
            var self = this;
            self.clear();
            self.$refs.dateFilter.selectedDate.end = adjustmentDate;
            self.$refs.dateFilter.selectedDate.start = selectionStart;
            window.DateFilterStore.state.rangeSelected = true;
        },
        applyRangeAdjustment: function () {
            //Checks that allow the date range to be adjusted once selected
            var self = this;
            var adjustmentDate = self.store.state.adjustmentDate;
            var selectionStart = null;
            var selectionEnd = null;

            if (self.$refs.dateFilter.selectedDate != null) {
                selectionStart = self.$refs.dateFilter.selectedDate.start;
                selectionEnd = self.$refs.dateFilter.selectedDate.end;
            } else {
                selectionStart = adjustmentDate != null ? adjustmentDate : null;
                this.state.data = { start: selectionStart, end: null };
            }

            //Calculate number of nights staying for selection 
            //if greater than 27 nights we reset the range selected bool and the picker returns to range selection
            var a = moment(adjustmentDate);
            var b = moment(selectionStart);
            var c = moment(selectionEnd);

            var nightsToStart = (a.diff(b, 'days') * -1);
            var nightsToEnd = (a.diff(c, 'days'));

            if (nightsToStart < -27 || nightsToEnd < -27) {
                window.DateFilterStore.state.rangeSelected = false;
            }

            //This determines the logic for whether we are editing a pre-existing range, and which date to edit (start or end)
            if (self.$refs.dateFilter.selectedDate && selectionStart != null && selectionEnd != null && window.DateFilterStore.state.rangeSelected) {
                if (adjustmentDate > selectionStart && adjustmentDate < selectionEnd && self.store.state[0].adjustedEnd) {
                    self.adjustStart(selectionEnd, adjustmentDate);
                    self.store.state[0].adjustedEnd = false;
                    self.store.state[0].adjustedStart = true;

                } else if (adjustmentDate > selectionStart && adjustmentDate < selectionEnd && self.store.state[0].adjustedEnd == false) {
                    self.adjustEnd(selectionStart, adjustmentDate);
                    self.store.state[0].adjustedEnd = true;
                    self.store.state[0].adjustedStart = false;

                } else if (adjustmentDate < selectionStart) {
                    if (self.store.state[0].adjustedStart) {
                        self.store.state[0].adjustedEnd = false;
                        self.store.state[0].adjustedStart = true;
                        this.enableRangeSelect();
                    } else {
                        self.adjustStart(selectionEnd, adjustmentDate);
                        self.store.state[0].adjustedEnd = false;
                        self.store.state[0].adjustedStart = true;
                    }

                } else if (adjustmentDate > selectionEnd) {
                    if (self.store.state[0].adjustedStart) {
                        self.adjustEnd(selectionStart, adjustmentDate);
                        self.store.state[0].adjustedEnd = true;
                        self.store.state[0].adjustedStart = false;
                    } else {
                        self.store.state[0].adjustedEnd = false;
                        self.store.state[0].adjustedStart = true;
                        this.enableRangeSelect();
                    }
                }
            } else {
                self.clear();
                if (!selectionEnd) {
                    self.$refs.dateFilter.selectedDate.start = selectionStart;
                    self.$refs.dateFilter.selectedDate.end = adjustmentDate;
                } else {
                    self.$refs.dateFilter.selectedDate.start = adjustmentDate;
                    self.$refs.dateFilter.selectedDate.end = null;
                }
            }
            this.toggleStyling();
        },
        clear: function (clearClicked) {

            //reset values for range adjustment
            this.updateNights(true);
            this.store.state[0].adjustedEnd = true;
            this.store.state[0].adjustedStart = false;
            window.DateFilterStore.state.rangeSelected = false;

            if (this.$refs.dateFilter.selectedDate != null) {
                this.store.applyFilter(this.id, this.$refs.dateFilter.selectedDate);
            }

            if (!(this.state.data.start != null && this.state.data.end != null)) {
                this.state.data.end = moment(this.state.data.start).add(1, 'days')._d
            }

            this.$data.errorOpacity = 0;
            this.store.setDefault(this.id);

            this.$refs.dateFilter.selectedDate = this.state.data;

            //We only want to tell the calendar to change back to the current month when we click the clear button
            //As we used clear in other locations to refresh dates
            if (clearClicked) {
                this.disableRangeSelect();
                this.store.state.adjustmentDate = undefined;
                this.store.state[this.id].previousDateRange = undefined;
            }

            if (this.$refs.ParkID != null) {
                this.state.data["ParkID"] = parseInt(this.$refs.ParkID.innerText);
            }

            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }

                delete cookie.Dates;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            } catch (e) {
            }

            window[this.eventBus].$emit(this.updateEvent, this.state.data);
            window[this.eventBus].$emit('date-filter-clear', this.state.data);

            //to clear quantity warnings when no pms result is being used
            window[this.eventBus].$emit("quantity-clear");

            this.toggleStyling();
        },
        formatDate: function(d) {
            return moment(d).format("ddd MMM DD");
        }

    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        dynamicDateStrings: function () {
            //Display plain english description of date selection at footer of calendar. Only when date selectionis not cleared.
            if (this.state.data != undefined && (!this.isDefault || (this.isDefault && this.DateFilterApplied())) ) {
                if (this.state.data.end != null) {

                    //Calculate number of nights staying for selection
                    var a = moment(this.state.data.start);
                    var b = moment(this.state.data.end);

                    if (this.$refs.dateFilter.selectedDate != null) {
                        a = moment(this.$refs.dateFilter.selectedDate.start);
                        b = moment(this.$refs.dateFilter.selectedDate.end);
                    }

                    var nights = (a.diff(b, 'days')) * -1;
                    var nightMessage = " (" + nights + " Nights)";

                    //remove plural if only 1 night
                    if (nights == 1) {
                        nightMessage = nightMessage.replace("s", "");
                    }

                    //If we are beyond the 27 night cap, restart date selection and show messgae
                    if (nights > 27) {
                        this.$data.maxNightsError = true;
                        this.enableRangeSelect();
                        return "Maximum 27 nights";
                    }
                    //If the end dates differ between state and refs upon selection the user has selected a end date prior to their start date.
                    //Update string to reflect this as the new start date and the previous start as the end date
                    else if (this.$refs.dateFilter.selectedDate != null
                        && this.state.data.end != this.$refs.dateFilter.selectedDate.end
                        && this.$refs.dateFilter.selectedDate.end != null) {
                        return this.state.data.start.toDateString().replace(this.state.data.start.getFullYear(), "") + " - " + this.$refs.dateFilter.selectedDate.end.toDateString().replace(this.state.data.end.getFullYear(), "") + nightMessage;
                    }

                    if (this.$data.maxNightsError) {
                        this.$data.maxNightsError = false;
                        return "Maximum 27 nights";
                    }

                    //Nights is NaN while range selection is active, only display check in date
                    if (isNaN(nights)) {
                        return this.state.data.start.toDateString().replace(this.state.data.start.getFullYear(), "") + " - Check Out";
                    }

                    return this.state.data.start.toDateString().replace(this.state.data.start.getFullYear(), "") + " - " + this.state.data.end.toDateString().replace(this.state.data.end.getFullYear(), "") + nightMessage;
                } else {
                    return this.state.data.start.toDateString().replace(this.state.data.start.getFullYear(), "") + " - Check Out";
                }
            } else {
                return "";
            }
        },
        dateFilterApplied() {
            return this.DateFilterApplied();
        },
        dynamicButtonDateStrings: function () {
            //Display the month and day for the filter buttons label. Only when date selectionis not cleared.
            if (this.state.data != undefined && (!this.isDefault || (this.isDefault && this.DateFilterApplied())) ) {
                if (this.state.data.end != null) {

                    if (this.$refs.dateFilter.selectedDate != null) {
                        start = moment(this.$refs.dateFilter.selectedDate.start)._d;
                        end = moment(this.$refs.dateFilter.selectedDate.end)._d;
                        if (start && end && this.$refs.dateFilter.selectedDate.end != null) {
                            return start.toDateString().replace(start.getFullYear(), "").substring(3) + " - " + end.toDateString().replace(end.getFullYear(), "").substring(3);
                        } else {
                            return this.state.data.start.toDateString().replace(this.state.data.start.getFullYear(), "").substring(3) + " - Check Out";
                        }
                    }
                    return this.state.data.start.toDateString().replace(this.state.data.start.getFullYear(), "").substring(3) + " - " + this.state.data.end.toDateString().replace(this.state.data.end.getFullYear(), "").substring(3);
                } else {
                    return this.state.data.start.toDateString().replace(this.state.data.start.getFullYear(), "").substring(3) + " - Check Out";
                }
            } else {
                return "Dates";
            }
        },
        errorOpacityLevel: function () {
            return this.$data.errorOpacity;
        },
        visible: function () {
            return this.$parent.visible;
        },
        isDefault: function () {
            const selectedStart = moment(this.state.data.start);
            const defaultStart = moment(this.store.default.start);
            const selectedEnd = moment(this.state.data.end);
            const defaultEnd = moment(this.store.default.end);

            //We explicitly check months days and years as moment sometimes produces very slightly different values with the same datetime,
            //causing same date comparisons to fail
            return selectedStart.year() === defaultStart.year()
                && selectedStart.month() === defaultStart.month()
                && selectedStart.date() === defaultStart.date()
                && selectedEnd.year() === defaultEnd.year()
                && selectedEnd.month() === defaultEnd.month()
                && selectedEnd.date() === defaultEnd.date();
        },
        initMinPage: function () {
            var today = new Date();
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                return {
                    month: today.getMonth() + 1,
                    year: today.getFullYear(),
                };
            }
            else {
                cookie = JSON.parse(cookie);
                if (!!cookie.Dates) {
                    var start = moment(cookie.Dates.start);
                    if (parseInt(start.format("YYYY")) >= new Date().getFullYear()) {
                        return {
                            month: parseInt(start.format("M")),
                            year: parseInt(start.format("YYYY")),
                        };
                    }
                }
                return {
                    month: today.getMonth() + 1,
                    year: today.getFullYear(),
                };
            }
        },
    },
    mounted: function () {
        var self = this;

        this.id = window.DateFilterStore.subscribeFilter();
        this.$nextTick(function () {
            if (this.$refs.ParkID != null) {
                try {
                    var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                    if (cookie != "") {

                        cookie = JSON.parse(cookie);
                        if (!!cookie.Dates && cookie.Dates.start != null && cookie.Dates.end != null) {
                            if (moment(cookie.Dates.end).toDate() > moment().toDate() && moment(cookie.Dates.start).toDate() >= moment().startOf('day').toDate()) {
                                var data = { start: moment(cookie.Dates.start).toDate(), end: moment(cookie.Dates.end).toDate() }
                                window.DateFilterStore.state.rangeSelected = true;
                                window[this.eventBus].$emit(this.updateEvent, data);
                            } else {
                                this.clear();
                            }
                        }
                    }
                }
                catch (e) {
                }
            } else {
                window[this.eventBus].$emit(this.updateEvent, this.state.data);
            }
        });

        if (this.defaultStartDate && this.defaultStartDate.length > 0 && this.defaultEndDate && this.defaultEndDate.length > 0 &&
            moment(this.defaultEndDate).toDate() > moment().toDate() && moment(this.defaultStartDate).toDate() >= moment().startOf('day').toDate()) {
            self.state.data.start = new Date(this.defaultStartDate);
            self.state.data.end = new Date(this.defaultEndDate);
            this.store.state.dateFilterApplied = true;
            this.updateNights();
            window[this.eventBus].$emit(this.updateEvent, this.state.data);
        }


        //Listener for date range adjustment functionality 
        window.FilterEventBus.$on('date-adjusted', function () {
            self.applyRangeAdjustment();
            var datePicker = self.$refs.dateFilter.$refs.datePicker;

            this.$nextTick(function () {
                if (datePicker.dragValue != null && window.DateFilterStore.state.rangeSelected) {
                    self.disableRangeSelect();
                }
            });
        });

        window.FilterEventBus.$on('page-change', function () {
            self.$nextTick(function () {
                self.toggleStyling();
            })
        });

        //Make sure we set ourself to closed when another filter is clicked
        window[this.eventBus].$on('filter-toggle-event', function (data) {
            if (data != self.$el && self.isOpen) {
                self.applyOnFilterChange();
                self.state.data = self.state.data;
                self.isOpen = false;
            }
        });
    },

});


;

window.DistanceFilterStore = {
    state: [],
    default: {
        distance: 100,
    },

    subscribeFilter: function () {
        this.state.push({
            id: this.state.length,
            data: this.default
        });

        return this.state.length - 1;
    },
    applyFilter:function(id, data) {
        this.state[id].data = data;
    },
    setDefault:function(id) {
        this.state[id].data = this.default;
    },
    clearFilter: function (id) {
        this.state[id].data = this.default;
    },
};

Vue.component('distance-filter-component', {
    props: ['event-bus', 'update-event'],
    data: function () {
        return {
            store: window.DistanceFilterStore,
            id: null,
            isOpen: false,
            scrollPos: 0,
        }
    },
    methods: {
        toggle: function () {

            this.isOpen = !this.isOpen;
            this.$parent.toggle();

            var self = this;
            if (this.isOpen) {

                //Disable mobile scrolling when open
                if (this.$mq == 'sm') {
                    this.$data.scrollPos = window.scrollY;
                }

                this.$nextTick(function () {
                    self.$refs.slider.value = this.state.data.distance;
                });
                //this.$refs.slider.value = this.state.data.distance;
            }

            window[this.eventBus].$emit('filter-toggle-event', this.$el);
        },
        close: function () {
            if (this.$refs.slider.value != this.store.default.distance)
            {
                this.applyFilter();
            }
            this.$refs.slider.value = this.state.data.distance;
            this.$parent.close();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
        },
        applyFilter: function () {

            //if (!navigator.geolocation) {
            //    return;
            //}

            var data = {
                distance: this.$refs.slider.value,
            };
            this.store.applyFilter(this.id, data);
            this.toggle();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }

            window[this.eventBus].$emit(this.updateEvent, this.state.data);

        },
        applyOnFilterChange: function () {
            if (this.$refs.slider != null)
            {
                var data = {
                    distance: this.$refs.slider.value,
                };
                this.store.applyFilter(this.id, data);
                window[this.eventBus].$emit(this.updateEvent, this.state.data);
            }

        },
        updateValues: function ()
        {
            //This is required to tie reactive slider values to dynamic string
            var data = {
                distance: this.$refs.slider.value,
            };
            this.store.applyFilter(this.id, data);
            this.$refs.slider.value = this.state.data.distance;
        },
        clear: function () {
            this.store.clearFilter(this.id);
            this.$refs.slider.value = this.state.data.distance;
            window[this.eventBus].$emit(this.updateEvent, 0);
        },
    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        dynamicButtonDistanceString: function ()
        {
            var cookieValue = this.state.data != undefined ? this.state.data.distance != this.store.default.distance : false;
            var edited = this.state.data != undefined && this.$refs.slider != undefined && this.$refs.slider.value != this.store.default.distance;

            //If we have values from the slider, and they're not the default, return the dynamic string.
            if (edited) {
                return this.$refs.slider.value + " km from me";
            }
            else if (cookieValue) {
                return this.state.data != undefined && this.$refs.slider != undefined && this.$refs.slider.value != this.store.default.distance ? this.$refs.slider.value + " km from me" : "Distance from me";
            } else
            {
                return "Distance from me";
            }
        },
        visible: function () {
            return this.$parent.visible;
        },
        isActive: function () {
            if (this.state && this.state.data) {

                if (this.isOpen) {
                    return true;
                }
                return this.state.data.distance != this.store.default.distance;
            }
            return false;
        }
    },
    mounted: function () {
        var self = this;
        this.id = window.DistanceFilterStore.subscribeFilter();

        //Make sure we set ourself to closed when another filter is clicked
        window[this.eventBus].$on('filter-toggle-event', function (data) {
            if (data != self.$el && self.isOpen) {
                self.applyOnFilterChange();
                self.state.data = self.state.data;
                self.isOpen = false;
            }
        });
    }

});
;
window.FilterEventBus = new Vue();


window.FilterEvents = {
    UPDATE_FILTERS: "update-filters",
};

;
window.GuestFilterStore = {
    state: [],
    default: {
            adults: 1,
            children: 0,
            infants: 0,
    },

    subscribeFilter: function () {
        var data = this.default;

        //see if we have a cookie to retrieve dates from
        try
        {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie != "") {

                cookie = JSON.parse(cookie);
                if (!!cookie.Guests) {
                    data = cookie.Guests;
                }
            }
        } catch (e)
        {
        }
        
        this.state.push({
            id: this.state.length,
            data: data
        });

        return this.state.length - 1;
    },
    applyFilter: function (id, data) {
        this.state[id].data = data;
        //when we apply the filter, we want to store the data in a cookie
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }
            cookie.Guests = data;
            CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
        }
        catch (e) {
        }
    },
    setDefault:function(id) {
        this.state[id].data = this.default;
    },
    isApplied: function () {
        return this.state[id].data.adults !== 1 && this.state[id].data.children !== 0 && this.state[id].data.infants !== 0;
    }
};

Vue.component('guest-filter-component', {
    props:['event-bus','update-event', 'default-adults', 'default-children', 'default-infants'],
    data: function () {
        return {
            store: window.GuestFilterStore,
            id: null,
            isOpen: false,
            scrollPos: 0,
        }
    },
    methods: {
        toggle: function () {
            this.isOpen = !this.isOpen;
            this.$parent.toggle();

            if (this.isOpen) {

                //Disable mobile scrolling when open
                if (this.$mq == 'sm') {
                    this.$data.scrollPos = window.scrollY;
                }


                this.$refs.adults.quantity = this.state.data.adults;
                this.$refs.children.quantity = this.state.data.children;
                this.$refs.infants.quantity = this.state.data.infants;
            }

            window[this.eventBus].$emit('filter-toggle-event', this.$el);
        },
        isActive: function () {
            if (this.state.data != undefined) {
                if (this.state.data.adults != this.store.default.adults) {
                    return true;
                }
                else if (this.state.data.children != this.store.default.children) {
                    return true;
                }
                else if (this.state.data.infants != this.store.default.infants) {
                    return true;
                } else if (this.isOpen) {
                    return true;
                }
            } 

            return false;
        },
        close: function () {
            this.applyFilter();
            this.$refs.adults.quantity = this.state.data.adults;
            this.$refs.children.quantity = this.state.data.children;
            this.$refs.infants.quantity = this.state.data.infants;
            this.$parent.close();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
        },
        applyFilter: function () {
            var data = {
                adults: this.$refs.adults.quantity,
                children: this.$refs.children.quantity,
                infants: this.$refs.infants.quantity,
            };

            this.store.applyFilter(this.id, data);
            this.toggle();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }

            window[this.eventBus].$emit(this.updateEvent, data);

        },
        applyOnFilterChange: function () {
            var data = {
                adults: this.$refs.adults.quantity,
                children: this.$refs.children.quantity,
                infants: this.$refs.infants.quantity,
            };
            

            this.store.applyFilter(this.id, data);
            window[this.eventBus].$emit(this.updateEvent, data);

        },
        clear: function () {
            this.store.setDefault(this.id);

            this.$refs.adults.quantity = this.$data.store.default.adults;
            this.$refs.children.quantity = this.$data.store.default.children;
            this.$refs.infants.quantity = this.$data.store.default.infants;
            
            var data = {
                adults: this.state.data.adults,
                children: this.state.data.children,
                infants: this.state.data.infants,
            };

            //Set the cookie to the default values
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie.Guests = data;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }

            window[this.eventBus].$emit(this.updateEvent, data);
        },
    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        canDecreaseAdults: function ()
        {
            return this.state.data.adults > 1;
        },
        visible: function () {
            return this.$parent.visible;
        },
        dynamicButtonGuestsString: function ()
        {
            if (this.state.data != undefined)
            {
                //TW: Ensures the button displays the correct values even when filter is closed (such as on page load)
                if (!this.isOpen) {
                    this.$refs.adults.quantity = this.state.data.adults;
                    this.$refs.children.quantity = this.state.data.children;
                    this.$refs.infants.quantity = this.state.data.infants;
                }

                if (this.$refs.adults.quantity > 1 || this.$refs.children.quantity > 0 || this.$refs.infants.quantity > 0) {
                    result = this.$refs.adults.quantity == 1 ? this.$refs.adults.quantity + " Guest" : this.$refs.adults.quantity + " Guests";
                    if (this.$refs.children.quantity > 0) {
                        result = (this.$refs.children.quantity + this.$refs.adults.quantity) + " Guests";
                    }
                    if (this.$refs.infants.quantity > 0) {
                        result += this.$refs.infants.quantity == 1 ? ", " + this.$refs.infants.quantity + " Infant" : ", " + this.$refs.infants.quantity + " Infants";
                    }
                    return result;
                } else
                {
                    return 'Guests';
                }
            }
        },
        isDefault: function () {
            if (this.state.data.adults != this.store.default.adults) {
                return false;
            }
            else if (this.state.data.children != this.store.default.children) {
                return false;
            }
            else if (this.state.data.infants != this.store.default.infants) {
                return false;
            }

            return true;
        }
    },
    mounted: function () {
        var self = this;
        var cookie = undefined;

        this.id = window.GuestFilterStore.subscribeFilter();
        this.$nextTick(function () {
            if (this.state.data != this.store.default) {
                //window[this.eventBus].$emit(this.updateEvent, this.state.data);
            }
        });

        try {
            cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }


        }
        catch (e) {
        }

        //If the cookie value for guests is absent or the value is the default (just 1 adult) then assign the provided values if applicable
        if (!cookie || (!cookie.Guests) ||
            (cookie.Guests.adults === 1 && cookie.Guests.children === 0 && cookie.Guests.infants === 0)) {
            if (this.defaultAdults && this.defaultAdults > 0) {
                self.state.data.adults = this.defaultAdults;
            }

            if (this.defaultChildren && this.defaultChildren > 0) {
                self.state.data.children = this.defaultChildren;
            }

            if (this.defaultInfants && this.defaultInfants > 0) {
                self.state.data.infants = this.defaultInfants;
            }
        }

        this.$nextTick(function () {
            if (this.state.data != this.store.default) {
                window[this.eventBus].$emit(this.updateEvent, this.state.data);
            }
        });


        //Make sure we set ourself to closed when another filter is clicked
        window[this.eventBus].$on('filter-toggle-event', function (data) {
            if (data != self.$el && self.isOpen) {

                self.applyOnFilterChange();

                self.state.data = self.state.data;
                self.isOpen = false;
            }
        });
    }

});


;
Vue.component('slider-filter', {
   
    /*
     * Initial state of the component's data.
     */
    props: ['store-name','apply-filter-function-name'],

    data: function () {
        return {
        }
    },
    methods: {
        toggle: function () {
            this.$parent.toggle();
            //resize event needed to display slider correctly
            this.$nextTick(function () { window.dispatchEvent(new Event('resize')) });
        },
        close: function () {
            this.$parent.close();
        },
        applyFilter: function () {
            var value = this.$refs.slider.value;
            window[this.storeName][this.applyFilterFunctionName](value);
            this.toggle();
        },
        active: function () {
            var values = this.store.distanceFromPark.value;

            if (values != undefined) {
                return true
            } else {
                return false;
            }
        },
        clear: function () {
            var value = window.SliderFilterStore.default.startPoint;
            window[this.storeName][this.applyFilterFunctionName](value);
            this.toggle();
        }
    },
    computed: {
        store: function () {
            return window[this.storeName].state;
        },
        visible: function () {
            return this.$parent.visible;
        }
    }

});

window.SliderFilterStore = {
    state: [],
    default: {
        distance: 100,
    },

    subscribeFilter: function () {
        this.state.push({
            id: this.state.length,
            data: this.default
        });

        return this.state.length - 1;
    },
    applyFilter:function(id, data) {
        this.state[id].data = data;
    },
    setDefault:function(id) {
        this.state[id].data = this.default;
    },
};

Vue.component('slider-filter-component', {
    props: ['event-bus', 'update-event'],
    data: function () {
        return {
            store: window.SliderFilterStore,
            id: null,
            isOpen: false,
            scrollPos: 0,
        }
    },
    methods: {
        toggle: function () {
            this.isOpen = !this.isOpen;
            this.$parent.toggle();

            var self = this;
            if (this.isOpen) {

                //Disable mobile scrolling when open
                if (this.$mq == 'sm') {
                    this.$data.scrollPos = window.scrollY;
                }

                this.$nextTick(function () {
                    self.$refs.slider.value = this.state.data.distance;
                });
                //this.$refs.slider.value = this.state.data.distance;
            }
            //resize event needed to display slider correctly
            this.$nextTick(function () { window.dispatchEvent(new Event('resize')) });

            window[this.eventBus].$emit('filter-toggle-event', this.$el);
        },
        close: function () {
            this.$refs.slider.value = this.state.data.distance;
            this.$parent.close();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
        },
        applyFilter: function () {
            var data = {
                distance: this.$refs.slider.value,
            };
            this.store.applyFilter(this.id, data);
            this.toggle();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }

            window[this.eventBus].$emit(this.updateEvent, this.state.data);

        },
        applyOnFilterChange: function () {
            var data = {
                distance: this.$refs.slider.value,
            };
            this.store.applyFilter(this.id, data);
            window[this.eventBus].$emit(this.updateEvent, this.state.data);
        },
        clear: function () {
            this.store.setDefault(this.id);
            this.$parent.close();
            this.isOpen = false;

            window[this.eventBus].$emit(this.updateEvent, this.state.data);
        },
    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        visible: function () {
            return this.$parent.visible;
        },
        isActive: function () {
            if (this.state && this.state.data) {

                if (this.isOpen) {
                    return true;
                }

                return this.state.data.isOn;
            }
            return false;
        }
    },
    mounted: function () {
        this.id = window.SliderFilterStore.subscribeFilter();

        //Make sure we set ourself to closed when another filter is clicked
        window[this.eventBus].$on('filter-toggle-event', function (data) {
            if (data != self.$el && self.isOpen) {
                self.applyOnFilterChange();
                self.state.data = self.state.data;
                self.isOpen = false;
            }
        });
    }

});
;
Vue.component('toggle-filter', {

    /*
     * Initial state of the component's data.
     */
    props: ['store-name', 'apply-filter-function-name'],

    data: function () {
        return {
        }
    },
    methods: {
        toggle: function () {
            this.$parent.toggle();
        },
        close: function () {
            this.$parent.close();
        },
        applyFilter: function () {
            window[this.storeName][this.applyFilterFunctionName]();
            this.toggle();
        },
        active: function () {
            var value = this.store.memberBenefits.value;
            return value;
        },
    },
    computed: {
        store: function () {
            return window[this.storeName].state;
        },
        visible: function () {
            return this.$parent.visible;
        }
    }

});


window.ToggleFilterStore = {
    state: [],
    default: {
        isOn: window.featureFlags.BAPI_4022,
    },

    subscribeFilter: function () {

        var data = this.default;

        //see if we have a cookie to retrieve dates from
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie != "") {

                cookie = JSON.parse(cookie);
                if (!!cookie.Toggle) {
                    data = cookie.Toggle;
                }
            }
        } catch (e) {
        }

        this.state.push({
            id: this.state.length,
            data: data
        });

        return this.state.length - 1;
    },
    applyFilter: function (id, data) {
        this.state[id].data = data;
    },
    setDefault: function (id) {
        this.state[id].data = this.default;
    },
};

window.AvailabilityToggleFilterStore = {
    state: [],
    default: {
        isOn: window.featureFlags.BAPI_4022,
    },

    subscribeFilter: function () {

        var data = this.default;

        this.state.push({
            id: this.state.length,
            data: data
        });

        return this.state.length - 1;
    },
    applyFilter: function (id, data) {
        this.state[id].data = data;
    },
    setDefault: function (id) {
        this.state[id].data = this.default;
    },
};

Vue.component('toggle-filter-component', {
    props: ['event-bus', 'update-event', 'default-value', 'availability-toggle'],
    data: function () {
        return {
            store: window.ToggleFilterStore,
            id: null,
            isOpen: false,
            scrollPos: 0,
        }
    },
    methods: {
        toggle: function () {
            this.isOpen = !this.isOpen;
            this.$parent.toggle();

            if (this.isOpen) {

                //Disable mobile scrolling when open
                if (this.$mq == 'sm') {
                    this.$data.scrollPos = window.scrollY;
                }

                this.$refs.toggle.checked = this.state.data.isOn;
            }

            window[this.eventBus].$emit('filter-toggle-event', this.$el);
        },
        close: function () {
            this.$refs.toggle.checked = this.state.data.isOn;
            this.$parent.close();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
        },
        applyFilter: function () {

            var data = {
                isOn: this.$refs.toggle.checked,
            };

            //Set the cookie to the selected value
            if (this.availabilityToggle != "true") {
                try {
                    var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                    if (cookie == "") {
                        cookie = {};
                    }
                    else {
                        cookie = JSON.parse(cookie);
                    }
                    cookie.Toggle = data;
                    CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
                }
                catch (e) {
                }
            }


            this.store.applyFilter(this.id, data);
            //this.toggle();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }

            window[this.eventBus].$emit(this.updateEvent, data);

        },
        applyOnFilterChange: function () {

            var data = {
                isOn: this.$refs.toggle.checked,
            };

            //Set the cookie to the selected value
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie.Toggle = data;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }


            this.store.applyFilter(this.id, data);
            window[this.eventBus].$emit(this.updateEvent, data);

        },
        clear: function () {
            this.store.setDefault(this.id);
            this.$parent.close();
            this.isOpen = false;

            var data = {
                isOn: this.state.data.isOn,
            };

            window[this.eventBus].$emit(this.updateEvent, data);
        },
    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        visible: function () {
            return this.$parent.visible;
        },
        isActive: function () {
            if (this.state && this.state.data) {

                if (this.isOpen) {
                    return true;
                }

                return this.state.data.isOn;
            }
            return false;
        },
        isApplied: function () {
            if (this.state && this.state.data) {
                return this.state.data.isOn;
            }
            return false;
        }
    },
    mounted: function () {
        var self = this;
        var cookie = undefined;

        if (this.availabilityToggle == "true") {
            this.id = window.AvailabilityToggleFilterStore.subscribeFilter();
            this.store = window.AvailabilityToggleFilterStore;
        } else {
            this.id = window.ToggleFilterStore.subscribeFilter();
        }

        try {
            cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }

        }
        catch (e) {
        }

        //If the cookie value for pet friendly is false and the provided filter value is true, then set the filter
        if (this.defaultValue && (!cookie || !cookie.Toggle.isOn)) {
            this.state.data.isOn = self.defaultValue;
        }

        this.$nextTick(function () {
            if (this.state.data != this.store.default) {
                window[this.eventBus].$emit(this.updateEvent, this.state.data);
            }
        });

        //Make sure we set ourself to closed when another filter is clicked
        window[this.eventBus].$on('filter-toggle-event', function (data) {
            if (data != self.$el && self.isOpen) {
                self.applyOnFilterChange();
                self.state.data = self.state.data;
                self.isOpen = false;
            }
        });
    }

});



;
Vue.component('two-way-slider-filter', {
   
    /*
     * Initial state of the component's data.
     */
    props: ['store-name','apply-filter-function-name'],

    data: function () {
        return {
        }
    },
    methods: {
        toggle: function () {
            this.$parent.toggle();
            //resize event needed to display slider correctly
            this.$nextTick(function () { window.dispatchEvent(new Event('resize')) });
        },
        close: function () {
            this.$parent.close();
        },
        applyFilter: function () {
            var value = this.$refs.slider.value;
            window[this.storeName][this.applyFilterFunctionName](value);
            this.toggle();
        }
    },
    computed: {
        store: function () {
            return window[this.storeName].state;
        },
        visible: function () {
            return this.$parent.visible;
        }
    }

});

window.TwoSliderFilterStore = {
    state: [],
    default: {
        startPoint: 0,
        endPoint: 999
    },

    subscribeFilter: function () {
        var data = this.default;

        //see if we have a cookie to retrieve the price range from
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie != "") {

                cookie = JSON.parse(cookie);
                if (!!cookie.Price) {
                    data = cookie.Price;
                }
            }
        } catch (e) {
        }

        this.state.push({
            id: this.state.length,
            data: data
        });
        return this.state.length - 1;
    },
    applyFilter: function (id, data) {

        //Set the cookie to the selected values
        try {
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }
            cookie.Price = data;
            CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
        }
        catch (e) {
        }

        this.state[id].data = data;
    },
    setDefault:function(id) {
        this.state[id].data = this.default;
    },
};

Vue.component('two-way-slider-filter-component', {
    props: ['event-bus', 'update-event'],
    data: function () {
        return {
            store: window.TwoSliderFilterStore,
            id: null,
            isOpen: false,
            scrollPos: 0,
        }
    },
    methods: {
        toggle: function () {
            this.isOpen = !this.isOpen;
            this.$parent.toggle();

            var self = this;
            if (this.isOpen) {

                //Disable mobile scrolling when open
                if (this.$mq == 'sm') {
                    this.$data.scrollPos = window.scrollY;
                }

                this.$nextTick(function () {
                    self.$refs.slider.value[0] = this.state.data.startPoint;
                    self.$refs.slider.value[1] = this.state.data.endPoint;
                });
                //this.$refs.slider.value = this.state.data.distance;
            }
            //resize event needed to display slider correctly
            this.$nextTick(function () { window.dispatchEvent(new Event('resize')) });

            window[this.eventBus].$emit('filter-toggle-event', this.$el);
        },
        close: function () {
            if (this.state.data != this.default) {
                this.applyFilter();
            }
            this.$refs.slider.value[0] = this.state.data.startPoint;
            this.$refs.slider.value[1] = this.state.data.endPoint;
            this.$parent.close();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }
        },
        applyFilter: function () {
            var data = {
                startPoint: this.$refs.slider.value[0],
                endPoint: this.$refs.slider.value[1]
            };
            this.store.applyFilter(this.id, data);
            this.toggle();
            this.isOpen = false;

            //re-enable mobile scrolling, return scrolling position to previous state
            if (this.$mq == 'sm') {
                document.getElementsByTagName('body')[0].style.position = '';
                window.scrollTo(0, parseInt(this.$data.scrollPos || '0'));
            }

            window[this.eventBus].$emit(this.updateEvent, this.state.data);

        },
        applyOnFilterChange: function () {
            var data = {
                startPoint: this.$refs.slider.value[0],
                endPoint: this.$refs.slider.value[1]
            };
            this.store.applyFilter(this.id, data);
            window[this.eventBus].$emit(this.updateEvent, this.state.data);

        },
        clear: function () {
            this.store.setDefault(this.id);
            
            this.$refs.slider.value = [this.state.data.startPoint, this.state.data.endPoint];

            var self = this;

            //Set the cookie to the default values
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie.Price = self.store.default;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
            }
            catch (e) {
            }

            window[this.eventBus].$emit(this.updateEvent, this.state.data);
        },
    },
    computed: {
        state: function () {
            if (this.id != null) {
                return this.store.state[this.id];
            }
            else {
                return {};
            }
        },
        dynamicButtonValueOneString: function ()
        {
            var cookieValue = this.state.data != undefined ? (this.state.data.endPoint != this.store.default.endPoint) || (this.state.data.startPoint != this.store.default.startPoint) : false;
            var edited = this.state.data != undefined ? (this.$refs.slider.value[1] != this.store.default.endPoint) || (this.$refs.slider.value[0] != this.store.default.startPoint) : false;

            //If we have edited the value using the slider we return that edited value, otherwise if we're pulling cookie values through we use state data
            if (edited) {
                return this.state.data != undefined && this.$refs.slider != undefined ? this.$refs.slider.value[0] : "";
            } else if (cookieValue) {
                return this.state.data != undefined && this.$refs.slider != undefined ? this.state.data.startPoint : "";
            }
        },
        dynamicButtonValueTwoString: function () {
            var cookieValue = this.state.data != undefined ? (this.state.data.endPoint != this.store.default.endPoint) || (this.state.data.startPoint != this.store.default.startPoint) : false;
            var edited = this.state.data != undefined ? (this.$refs.slider.value[1] != this.store.default.endPoint) || (this.$refs.slider.value[0] != this.store.default.startPoint) : false;

            //If we have edited the value using the slider we return that edited value, otherwise if we're pulling cookie values through we use state data
            if (edited) {
                return this.state.data != undefined && this.$refs.slider != undefined ? this.$refs.slider.value[1] : "";
            } else if (cookieValue)
            {
                return this.state.data != undefined && this.$refs.slider != undefined ? this.state.data.endPoint : "";
            }
        },
        visible: function () {
            return this.$parent.visible;
        },
        isActive: function () {
            if (this.state && this.state.data) {

                if (this.isOpen) {
                    return true;
                }

                return (this.state.data.endPoint != this.store.default.endPoint || this.state.data.startPoint != this.store.default.startPoint);
            }
            return false;
        }
    },
    mounted: function () {
        var self = this;

        this.id = window.TwoSliderFilterStore.subscribeFilter();
        this.$nextTick(function () {
            if (this.state.data != this.store.default) {
                window[this.eventBus].$emit(this.updateEvent, this.state.data);
            }
        });

        //Make sure we set ourself to closed when another filter is clicked
        window[this.eventBus].$on('filter-toggle-event', function (data) {
            if (data != self.$el && self.isOpen) {
                self.applyOnFilterChange();
                self.state.data = self.state.data;
                self.isOpen = false;
            }
        });
    }

});
;
Vue.component('v-calendar-mobile-wrapper', {
    props: {
        toDateOnly: 
        {
            default: false
        },
    },
    template: '<div style="display:none;"></div>',
    computed:
    {
        filterWindowOpen: function ()
        {
            return window.AccommodationStore.state.filterWindowOpen;
        },
    },
    methods:
    {
        IosSelect: function () {
            var self = this;
            var IsIOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);

            //We need to know which iOS version is in use, as this workaround is not required for iOS 13
            var appVersion = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
            var appVersionNumber = appVersion != null ? [parseInt(appVersion[1], 10), parseInt(appVersion[2], 10), parseInt(appVersion[3] || 0, 10)] : [0];

            //TW: If we are using an ios device, treat a tap on a day in the calendar as a double tap.
            //We unbind mouseover events first as this tended to fire twice.
            if (IsIOS && appVersionNumber[0] < 12) {
                $('.c-day').unbind('mouseover');
                $('.c-day').on('mouseover', function (event) {
                    if (IsIOS) {
                        event.target.click();
                    }
                });
            }
        },
        DynamicZindex: function ()
        {
            if (window.AccommodationStore != undefined && window.AccommodationStore != null)
            {
                var inFront = false;

                var observer = new MutationObserver(function (mutations) {
                    mutations.forEach(function (mutationRecord)
                    {
                        if (!inFront) {
                            $('.c-accommodation-filter-wrapper').css('z-index', '10');
                            inFront = true;
                        } else
                        {
                            $('.c-accommodation-filter-wrapper').css('z-index', '7');
                            inFront = false;
                        }
                    });
                });

                var target = $('.c-filter__panel');

                if (target.length > 0)
                {
                    for (var i = 0; i < target.length; i++)
                    {
                        observer.observe(target[i], { attributes: true, attributeFilter: ['style'] });
                    }
                }

            }
        }
    },
    mounted: function ()
    {
        window.VcalendarMobileEventBus = new Vue();
        var self = this;

        //Click events to ensure menus and filter windows stack correctly on accommodation options page
        self.DynamicZindex();

        //TW: Set up for ios double press fix
        self.IosSelect();
        $('.c-button--calendar-nav').on('click', function () {
            setTimeout(function () { self.IosSelect(); }, 450)
        });
        
        window.AccommodationEventBus.$on('from-date-selected', function () {
            self.toDateOnly = true;
        });

        window.VcalendarMobileEventBus.$on('month-change', function () {
            setTimeout(function () { self.IosSelect(); }, 450)
        });
    }
});;
Vue.use(AsyncComputed);

Vue.component('accommodation-calendar', {
    //props: ['ParkId', 'UnavailableDates', 'AccommodationId'],
    mixins: [MIXIN_BOOKING_WIDGET],
    data: function () {
        return {
            store: window.BookingStore,
            availabilityLoading: false,
            cleared: false,
            maxNightsError: false,
            currentPage: {}
        }
    },
    computed: {
        availableDateRangesForCalendar: function () {
            var start = moment(this.currentPage.year + "-" + this.currentPage.month + "-01", "YYYY-MM-DD");
            var end = moment(start).add(1,'month').endOf('month');
            return this.getAvailableRangesForDateRange(start, end);
        },
        state: function () {
            return this.store.state;
        },
        props: function () {
            return {
                ClearDates: this.ClearDates,
                DatesSelected: this.datesSelected,
                CheckoutAvailability: this.CheckoutAvailability,
                dateSelectionObject: this.dateSelectionObject,
                dynamicDateStrings: this.dynamicDateStrings,
            };
        },
        dynamicDateStrings: function () {
            //Display plain english description of date selection at footer of calendar. Only when date selectionis not cleared.
            if (this.state.startDate != null) {
                if (this.state.endDate != null) {

                    //Calculate number of nights staying for selection
                    var a = moment(this.state.startDate);
                    var b = moment(this.state.endDate);
                    var nights = (a.diff(b, 'days')) * -1;
                    var nightMessage = " (" + nights + " Nights)";

                    //remove plural if only 1 night
                    if (nights == 1) {
                        nightMessage = nightMessage.replace("s", "");
                    }

                    if (this.$refs.dateInput.selectedDate != null
                        && this.state.endDate._d != this.$refs.dateInput.selectedDate.end
                        && this.$refs.dateInput.selectedDate.end != null) {
                        return this.state.startDate._d.toDateString().replace(this.state.startDate._d.getFullYear(), "") + " - " + this.$refs.dateInput.selectedDate.end.toDateString().replace(this.state.endDate._d.getFullYear(), "") + nightMessage;
                    }

                    //Nights is NaN while range selection is active, only display check in date
                    if (isNaN(nights)) {
                        return this.state.data.start.toDateString().replace(this.state.data.start.getFullYear(), "") + " - Check Out";
                    }

                    return this.state.startDate._d.toDateString().replace(this.state.startDate._d.getFullYear(), "") + " - " + this.state.endDate._d.toDateString().replace(this.state.startDate._d.getFullYear(), "") + nightMessage;
                } else {
                    var dragMessage = "";
                    var nightMessage = "";

                    if (this.$refs.dateInput.$refs.calendar.dragValue != null && this.$refs.dateInput.$refs.calendar.dragValue != undefined)
                    {
                        dragMessage = this.state.startDate._d.toDateString().replace(this.state.startDate._d.getFullYear(), "") + " - " + this.$refs.dateInput.$refs.calendar.dragValue.end.toDateString().replace(this.$refs.dateInput.$refs.calendar.dragValue.end.getFullYear(), "")
                        var a = moment(this.state.startDate);
                        var b = moment(this.$refs.dateInput.$refs.calendar.dragValue.end);
                        var nights = (a.diff(b, 'days')) * -1;
                        if (nights == 0) {
                            nightMessage = "Check out";
                            dragMessage = this.state.startDate._d.toDateString().replace(this.state.startDate._d.getFullYear(), "") + " - ";
                        } else
                        {
                            nightMessage = nights == 1 ? " (" + nights + " Night)" : "(" + nights + " Nights)";
                        }
                    }
                    return dragMessage + nightMessage;
                }
            } else {
                return "";
            }
        },
    },
    methods: {
        GetMoreAvailability: _.debounce(function (obj) {
            var self = this;
            var startDate = moment(obj.year + "-" + obj.month + "-01", "YYYY-MM-DD");
            var endDate = moment(startDate).add(1, 'month').endOf("month").add(1, 'days');

            var request = {
                ParkID: self.currentAccommodation.ParkID,
                StartDate: startDate.format("YYYY-MM-DD"),
                EndDate: endDate.format("YYYY-MM-DD"),
            };

            self.availabilityLoading = true;
            self.store.GetAvailability(request, function () {
                self.availabilityLoading = false;
            }, function () {
                Common.ShowError("Unable to retrieve availability.");
                self.availabilityLoading = false;
            });

        }, 750),
        ClearDates: function (clicked) {
            var self = this;
            self.store.clearDates();
            if (clicked)
            {
                this.store.state.showMaxAccommodationError = false;
                this.disableRangeSelect();
                this.$data.cleared = true;
                this.store.state.rangeSelected = false;
                this.store.state.adjustmentDate = null;
                window.BookingEventBus.$emit("accommodation-calendar-cleared");
                //We set the offer code to the default, this way when re-selecting dates it will default to the 
                //cheapest price and ignore previously chosen deal
                var cacheData = window.BookingStore.GetCurrentAccommodation();
                window.BookingStore.state.currentOfferCode = cacheData.AvailabilityCacheData.DefaultRateID;
            }


            window.BookingEventBus.$emit("DATE-CHANGED");
            self.UpdateCookie(null);
        },
        CheckoutAvailability: function () {
            Vue.nextTick(function () {
                var self = this;
                this.$('.c-day').unbind('click');
                this.$('.c-day').on('click', function (event) { self.window.BookingEventBus.$emit('day-clicked', event.target) });

                //TW: If we are using an ios device, treat a tap on a day in the calendar as a double tap.
                //We unbind mouseover events first as this tended to fire twice.
                $('.c-day').unbind('mouseover');
                $('.c-day').on('mouseover', function (event) {
                    var IsIOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);

                    if (IsIOS && self.toDateOnly) {
                        event.target.click();
                        toDateOnly = false;
                    }
                    else {
                        if (IsIOS && self.fromDateSelected) {
                            event.target.click();
                        }
                        self.fromDateSelected = !self.fromDateSelected;
                    }
                });

            });
        },
        enableRangeSelect: function () {
            //This disregards the end date of a selected range and re-starts the range selection functionality
            var self = this;
            var datePicker = self.$refs.dateInput.$refs.calendar;
            var dateInput = self.$refs.dateInput;

            if (dateInput.selectedDate.start.toDateString() == this.store.state.adjustmentDate.toDateString()) {
                datePicker.$children[0].dragValue = { start: dateInput.selectedDate.start, end: moment(dateInput.selectedDate.start).add(1, 'days')._d };
                datePicker.$children[0].value.start = dateInput.selectedDate.start;
                datePicker.$children[0].value.end = null;
            }
            else if (dateInput.selectedDate.end.toDateString() == this.store.state.adjustmentDate.toDateString()) {
                datePicker.$children[0].dragValue = { start: dateInput.selectedDate.end, end: moment(dateInput.selectedDate.end).add(1, 'days')._d };
                datePicker.$children[0].value.start = dateInput.selectedDate.end;
                datePicker.$children[0].value.end = null;
            }
            dateInput.isDragging = true;
            window.DateFilterStore.state.rangeSelected = false;
        },
        disableRangeSelect: function (startDate, endDate) {
            var self = this;
            self.$nextTick(function () {
                var datePicker = self.$refs.dateInput.$refs.calendar;
                var dateInput = self.$refs.dateInput;
                if (datePicker.dragValue != null) {
                    //Prevent calendar from entering range selection
                    datePicker.$children[0].dragValue = null;
                    datePicker.$children[0].value = { start: startDate, end: endDate};
                    self.$refs.dateInput.isDragging = false;
                }

                self.$refs.dateInput.selectedDate = {
                    start: startDate,
                    end: endDate
                };

                self.$forceUpdate();
            });
        },
        adjustStart: function (selectionEnd, adjustmentDate) {
            var self = this;
            self.ClearDates();
            self.$refs.dateInput.selectedDate.start = adjustmentDate;
            self.$refs.dateInput.selectedDate.end = selectionEnd;
            window.DateFilterStore.state.rangeSelected = true;
        },
        adjustEnd: function (selectionStart, adjustmentDate) {
            var self = this;
            self.ClearDates();
            self.$refs.dateInput.selectedDate.end = adjustmentDate;
            self.$refs.dateInput.selectedDate.start = selectionStart;
            window.DateFilterStore.state.rangeSelected = true;
        },
        applyRangeAdjustment: function () {
            //Checks that allow the date range to be adjusted once selected
            var self = this;
            var adjustmentDate = self.store.state.adjustmentDate;
            var selectionStart = null;
            var selectionEnd = null;

            if (self.$refs.dateInput.selectedDate != null)
            {
                selectionStart = self.$refs.dateInput.selectedDate.start;
                selectionEnd = self.$refs.dateInput.selectedDate.end;
            

                //Calculate number of nights staying for selection 
                //if greater than 27 nights we reset the range selected bool and the picker returns to range selection
                var a = moment(adjustmentDate);
                var b = moment(selectionStart);
                var c = moment(selectionEnd);

                var nightsToStart = (a.diff(b, 'days') * -1);
                var nightsToEnd = (a.diff(c, 'days'));

                if (nightsToStart < -27 || nightsToEnd < -27) {
                    window.BookingStore.state.rangeSelected = false;
                }

                if (adjustmentDate > selectionEnd && !self.store.state.adjustedStart) {
                    window.BookingStore.state.rangeSelected = false;
                    self.store.state.adjustedEnd = false;
                    self.store.state.adjustedStart = false;
                }
                else if (adjustmentDate < selectionEnd && self.store.state.adjustedStart)
                {
                    window.BookingStore.state.rangeSelected = false;
                    self.store.state.adjustedEnd = false;
                    self.store.state.adjustedStart = false;
                }

                //This determines the logic for whether we are editing a pre-existing range, and which date to edit (start or end)
                if (self.$refs.dateInput.selectedDate && selectionStart != null && selectionEnd != null && window.BookingStore.state.rangeSelected) {
                    if (adjustmentDate > selectionStart && adjustmentDate < selectionEnd && self.store.state.adjustedEnd) {
                        self.adjustStart(selectionEnd, adjustmentDate);
                        self.store.state.adjustedEnd = false;
                        self.store.state.adjustedStart = true;

                    } else if (adjustmentDate > selectionStart && adjustmentDate < selectionEnd && self.store.state.adjustedEnd == false) {
                        self.adjustEnd(selectionStart, adjustmentDate);
                        self.store.state.adjustedEnd = true;
                        self.store.state.adjustedStart = false;

                    } else if (adjustmentDate < selectionStart) {
                        self.adjustStart(selectionEnd, adjustmentDate);
                        self.store.state.adjustedEnd = false;
                        self.store.state.adjustedStart = true;

                    } else if (adjustmentDate > selectionEnd) {
                        self.adjustEnd(selectionStart, adjustmentDate);
                        self.store.state.adjustedEnd = true;
                        self.store.state.adjustedStart = false;
                    }

                    self.store.state.startDate = moment(self.$refs.dateInput.$refs.calendar.value.start);
                    self.store.state.endDate = moment(self.$refs.dateInput.$refs.calendar.value.end);

                } else {
                    self.ClearDates();
                    if (!selectionEnd) {
                        self.$refs.dateInput.selectedDate.start = self.$refs.dateInput.$refs.calendar.value.start;
                        self.$refs.dateInput.selectedDate.end = adjustmentDate;
                    } else {
                        self.$refs.dateInput.selectedDate.start = adjustmentDate;
                        self.$refs.dateInput.selectedDate.end = null;
                    }
                }
            }
        },
        UpdateCookie: function (data) {
            //when we apply the filter, we want to store the data in a cookie
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }

            cookie.Dates = data;
            CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
        },
    },
    mounted: function () {
        var self = this;

        self.$nextTick(function () {
            self.CheckoutAvailability();
        });

        this.$refs.dateInput.$refs.calendar.$on('update:fromPage', function (obj) {
            if (!!obj) {
                self.currentPage = obj;
                //we set this here because even though we debounce the requests, we need to make sure the user cant quickly select a date.
                self.availabilityLoading = true;
                self.GetMoreAvailability(obj);
            } else {
                var m = new moment(); // use the current date if we have not been given a date
                var newObj = {
                    year: m.year(),
                    month: m.month() + 1, // moment uses a 0 (zero) index for month so we need to add one month
                }
                self.currentPage = newObj;
                self.availabilityLoading = true;
                self.GetMoreAvailability(newObj);
            }
        });

        self.$watch('$refs.dateInput.selectedDate', function (newVal, oldVal) {

            if (newVal != null) {
                if (newVal.start != null && newVal.end != null) {
                    var startMoment = moment(newVal.start);
                    var endMoment = moment(newVal.end);

                    if (self.store.state.startDate != null && self.store.state.endDate != null) {
                        if (self.store.state.startDate.isSame(startMoment) && self.store.state.endDate.isSame(endMoment)) {
                            return;
                        }
                    }


                    self.store.state.startDate = moment(newVal.start);
                    self.store.state.endDate = moment(newVal.end);
                    window.BookingEventBus.$emit("DATE-CHANGED");

                    self.UpdateCookie(newVal);
                    self.store.UpdatePrice();
                } else if (newVal.start != null && newVal.end == null)
                {
                    self.store.state.startDate = moment(self.$refs.dateInput.$refs.calendar.value.start);;
                }
            }


        });

        window.BookingEventBus.$on("DATE-CHANGED", function () {

            this.$nextTick(function () {

                if (self.state.startDate && self.state.endDate) {
                    self.$refs.dateInput.selectedDate = {
                        start: self.state.startDate.toDate(),
                        end: self.state.endDate.toDate()
                    };
                } 
                else {
                    self.$refs.dateInput.selectedDate = null;
                }

                self.$forceUpdate();

            });
        });


        if (this.state.startDate != null && this.state.endDate != null) {

            //we need to use the next tick otherwise the display goes all funky
            this.$nextTick(function () {
                self.$refs.dateInput.selectedDate = {
                    start: self.state.startDate.toDate(),
                    end: self.state.endDate.toDate()
                }

            });
        }

        //Listener for invalid date adjustment
        window.BookingEventBus.$on("range-contains-unavailable", function () {
            window.BookingStore.state.rangeSelected = false;
        });

        //Listener for date range adjustment functionality 
        window.BookingEventBus.$on('date-adjusted', function (data) {
            if (data != 'widget')
            {
                var datePicker = self.$refs.dateInput.$refs.calendar;

                if (datePicker.value != null) {
                    self.store.state.savedCalendarValue = datePicker.value;
                } else if (!self.$data.cleared) {
                    datePicker.value = self.store.state.savedCalendarValue;
                    self.$refs.dateInput.selectedDate = self.store.state.savedCalendarValue;
                } else
                {
                    self.$data.cleared = false;
                }
                self.applyRangeAdjustment();

                if (datePicker.value != null)
                {
                    var startDate = datePicker.value.start;
                    var endDate = datePicker.value.end;
                }

                this.$nextTick(function () {
                    if (datePicker.dragValue != null && window.BookingStore.state.rangeSelected) {
                        self.disableRangeSelect(startDate, endDate);
                    }
                });
            }
        });
    }

});;
Vue.component('accommodation-type', {
    mixins: [MIXIN_BOOKING_WIDGET],
    template: "#AccommodationTypeTemplate",


    data: function () {
        return {
            
        }
    },

    computed: {
        accommodations: function () {
            return this.store.state.accommodation;
        },
        datesAreDefault: function () {
            return (!this.store.state.startDate && !this.store.state.endDate);
        },
    },
    methods: {
        changeAccommodation: function () {
            if (!this.datesAreDefault) {
                this.store.UpdatePrice();
            }
        }
    },
    



});
;
Vue.component('booking-add-to-cart-wrapper', {
    mixins: [MIXIN_BOOKING_WIDGET],
    props: {
        isQuickBooking: false,
    },
    data: function () {
        return {
            store: window.BookingStore,
            addingToCart: false,
        }
    },
    computed: {
        state: function () {
            return this.store.state;
        },
        isLoading: function () {
            if (this.isQuickBooking)
            {
                return this.state.quickBooking.PriceLoading || this.state.addingToCart;
            }
            return this.state.priceLoading || this.state.addingToCart;
        },
        canQuickBook: function ()
        {
            if (this.isQuickBooking) {
                return this.state.canAddToCart;
            } else {
                return false;
            }
        },
    },
    methods: {
        datesFailedValidation: function () {
            if ($('#check_in_date_parsed').val() == "") {
                return true;
            } else return false;
        },
        equipmentFailedValidation: function () {
            if ($('#equipment').val() == null) {
                return true;
            } else return false;
        },
        widthFailedValidation: function () {
            if ($('#width').val() == undefined) {
                return true;
            } else
            {
                return false;
            }
        },
        lengthFailedValidation: function () {
            if ($('#length').val() == undefined) {
                return true;
            } else {
                return false;
            }
        },
        showValidation: function ()
        {
            if (this.store.state.noTariffsAvailable) {
                $('.no-tariffs-available').addClass('has-error');
                //scroll to the invalid element
                $('html, body').animate({
                    scrollTop: $(".has-error").offset().top - 200
                }, 1000);

                return;
            }

            //When the user clicks add to cart with no dates selected.
            if (this.datesFailedValidation())
            {
                $('.c-input-date').addClass('has-error');
                $('.c-booking-date-error').css('opacity', '100');
            }

            //When the user clicks add to cart with no equipment selected.
            if (this.equipmentFailedValidation())
            {
                $('.c-select ').addClass('has-error');
                $('.equipment-selector').addClass('equipment-selector-error');
                $('.c-booking-equipment-error').css('opacity', '100');
                $('.c-booking-equipment-selector-error').css('opacity', '100');
            }

            //When the user clicks add to cart with no equipment length selected.
            if (this.lengthFailedValidation())
            {
                $('#length').closest('.c-field').addClass('has-error');
                $('.equipment-selector').addClass('equipment-selector-error');
                $('.c-booking-equipment-size-error').css('opacity', '100');
                $('.c-booking-equipment-selector-error').css('opacity', '100');
            }

            //When the user clicks add to cart with no equipment width selected.
            if (this.widthFailedValidation())
            {
                $('#width').closest('.c-field').addClass('has-error');
                $('.equipment-selector').addClass('equipment-selector-error');
                $('.c-booking-equipment-size-error').css('opacity', '100');
                $('.c-booking-equipment-selector-error').css('opacity', '100');
            }

            

        },
        hideDateValidation: function ()
        {
            $('.c-input-date').removeClass('has-error');
            $('.c-booking-date-error').css('opacity', 0);
        },
        hideEquipmentValidation: function () {
            $('.c-select ').removeClass('has-error');
            $('.equipment-selector').removeClass('equipment-selector-error');
            $('.c-booking-equipment-error').css('opacity', 0);
            $('.c-booking-equipment-selector-error').css('opacity', 0);
        },
        hideWidthValidation: function ()
        {
            $('#width').closest('.c-field').removeClass('has-error');
            $('.equipment-selector').removeClass('equipment-selector-error');
            $('.c-booking-equipment-size-error').css('opacity', 0);
        },
        hideLengthValidation: function ()
        {
            $('#length').closest('.c-field').removeClass('has-error');
            $('.equipment-selector').removeClass('equipment-selector-error');
            $('.c-booking-equipment-size-error').css('opacity', 0);
        },
        addToCart: function () {
            this.store.addToCart();
        }
    },
    mounted: function ()
    {
        var self = this;

        //If the user opens the date picker we want to remove validation errors
        $('.c-input-date').on('click', function () {
            self.hideDateValidation();
        });

        $('.c-select__input').on('click', function () {
            self.hideEquipmentValidation();
        });
        
        $('#width').on('click', function () {
            self.hideWidthValidation();
        });

        $('#length').on('click', function () {
            self.hideLengthValidation();
        });
    }

});
;
Vue.component('booking-free-membership-message', {
    template: '#BookingFreeMembershipMessage',
    mixins: [MIXIN_BOOKING_WIDGET, MIXIN_MEMBERSHIP],
    props: ["allotment", "canAddToCart"],
    data: function () {
        return {
            showUpdatedMessage: window.featureFlags.BAPI_3771_updated_free_membership_modal,
        };
    },
    computed: {
        showFreeMembershipMessage: function () {

            if (!this.isTotalPrice) {
                //this returns the first price as it should be returning "tonights" price
                window.BookingEventBus.$emit('free-membership-update', false);
            }
            else {
                if (this.allotment != undefined && this.datesSelected) {
                    var price = this.RoundPrice(this.allotment.Total);
                    // The booking total must be 500, and the discount must be 50 or higher (the cost of a membership)
                    if (price >= 500 && this.allotment.MemberDiscount >= 50 && window.ACCOMMODATION_TYPE != "Site" && this.isPerksPlusMember == false && this.isVipPerksMember == false) {
                        window.BookingEventBus.$emit('free-membership-update', true);
                        return true;
                    }
                    else if (price <= 500 && this.allotment.MemberDiscount >= 50 && window.ACCOMMODATION_TYPE != "Site" && this.isPerksPlusMember == false && this.isVipPerksMember == false) {
                        window.BookingEventBus.$emit('discount-membership-update', true);
                        return true;
                    }
                }
            }
            window.BookingEventBus.$emit('free-membership-update', false);
            return false;
        },
        isTotalPrice: function () {
            return !!this.allotment;
        },
    }
});;
window.BookingEventBus = new Vue();

window.eEquipmentUnitOfLength = {
    Metres: 0,
    Feet: 1
};

window.BookingStore = {
    state: {
        equipment: {
            Width: null,
            Length: null,
            Unit: window.eEquipmentUnitOfLength.Metres,
            EquipmentTypeID: null,
        },
        quickBooking:
        {
            AccommodationType: "",
            ParkSelectionID: "",
            ParkSelectionName: "",
            AccommodationSelectionID: "",
            PriceLoading: true,
            CurrentAllotmentSelection: [],
            AllUnavailable: false,
            isPark: false,
        },
        EquipmentTypes: [],
        accommodation: [],
        showPriceError: false,
        canAddToCart: false,
        priceLoading: true,
        loadingCounter: 0,
        priceLoadError: false,
        addingToCart: false,
        UnitValuesMetres: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
        UnitValuesFeet: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
        adults: 2,
        children: 0,
        infants: 0,
        startDate: null,
        endDate: null,
        selectingDates: false,
        stayToDateOnly: false,
        dateClicked: null,
        accommodationId: null,
        currentOfferCode: null,
        dataPrefilled: false,
        isOnDealPage: false,
        minDate: null,
        maxDate: null,
        adjustmentDate: null,
        adjustedEnd: false,
        adjustedStart: false,
        savedCalendarValue: null,
        bookingWidgetCalendarOpen: false,
        isCheckIn: false,
        showChevrons: false,
        rangeSelected: false,
        currentAvailabilityRange: {},
        noTariffsAvailable: false,
        showMaxAccommodationError: false
    },
    clearDates: function () {
        this.state.startDate = null;
        this.state.endDate = null;
        this.state.canCheckout = true;
        this.state.canCheckin = true;

        if (this.state.accommodation.length > 0) {
            for (var i = 0; i < this.state.accommodation.length; i++) {

                var accom = JSON.parse(JSON.stringify(this.state.accommodation[i]));
                this.state.accommodation.splice(i, 1);

                accom.CurrentPMSResult = [];

                this.state.accommodation.push(accom);
            }
        }

        //hide any quantity messaging
        window.BookingEventBus.$emit("quantity-update", 0);
    },
    showPriceError: function () {
        this.state.showPriceError = true;
        this.state.canAddToCart = false;
    },
    populateAccommodation: function (accommodation, searchMode) {

        if (accommodation.length > 0) {
            for (var i = 0; i < accommodation.length; i++) {

                var templateObject = {
                    AvailabilityCacheData: {},
                    CurrentPMSResult: [],
                };

                var combined = $.extend(accommodation[i], templateObject);

                this.state.accommodation.push(combined);
            }

            if (searchMode) {
                this.state.accommodationId = this.state.accommodation[0].AccommodationId;
            } else {
                this.state.accommodationId = this.state.accommodation[0].AccommodationID;
            }
        }
        else {
            console.error("No accommodation found");
        }
    },
    GetCurrentAccommodation: function () {
        var accom = _.find(this.state.accommodation, { AccommodationID: this.state.accommodationId });

        if (!accom) {
            accom = _.find(this.state.accommodation, { AccommodationId: this.state.accommodationId });
        }

        return accom;
    },
    GetCurrentAllotment: function () {
        var currentAllotment = _.find(this.GetCurrentAccommodation().CurrentPMSResult, { Offercode: this.state.currentOfferCode });
        this.state.quickBooking.CurrentAllotmentSelection = currentAllotment;
        return currentAllotment;
    },
    ReloadPrice: function () {
        this.UpdatePrice();
    },
    UpdatePrice: function () {
        this.SetPriceLoading();
        this.state.showMaxAccommodationError = false;
        var self = this;

        var accom = this.GetCurrentAccommodation();

        if (accom != undefined)
        {
            var request = {
                //ChargeTypeID: chargeId,
                AccommodationID: accom.AccommodationID,
                NumAdults: self.state.adults,
                NumKids: self.state.children,
                NumInfants: self.state.infants,
                Width: self.state.equipment.Width,
                Length: self.state.equipment.Length,
                Unit: self.state.equipment.Unit,
                Type: self.state.equipment.EquipmentTypeID,

                UseCache: true,
            }

            if (!request.AccommodationID) {
                request.AccommodationID = accom.AccommodationId;
            }

            if (!self.state.startDate) {
                request.ArrivalDate = moment().format("YYYY-MM-DD");
            }
            else {
                request.ArrivalDate = self.state.startDate.format("YYYY-MM-DD");
            }
            if (!self.state.endDate) {
                request.DepartingDate = moment().add(1, 'day').format("YYYY-MM-DD");
            }
            else {
                request.DepartingDate = self.state.endDate.format("YYYY-MM-DD");
            }

            $.ajax({
                type: 'GET',
                url: '/api/Booking/GetBookingAvailability',
                contentType: 'application/json; charset=utf-8',
                data: request,
                success: function (data) {
                    if (data.ResponseStatus == eHttpResponseStatus.Ok) {

                        self.ProcessPMSResults(data);
                        self.SetPriceFinishedLoading();

                    }
                    else {
                        self.SetPriceLoadingError();
                        Common.ShowErrorStatusMessages(data.StatusMessages);
                    }



                },
                error: function (xhr, ajaxOptions, thrownError) {
                    self.SetPriceLoadingError();
                }

            });
        }

    },
    ProcessAvailabilityCacheData: function (data) {
        //this function is used to collate all the data retrieved from the availability cache per accommodation
        var self = this;
        var isNew = false;

        for (var i = 0; i < this.state.accommodation.length; i++) {
            for (var j = 0; j < data.length; j++) {
                if (this.state.accommodation[i].AccommodationID == data[j].AccommodationID || this.state.accommodation[i].AccommodationId == data[j].AccommodationID) {
                    if (typeof (this.state.accommodation[i].AvailabilityCacheData.DefaultRate) == 'undefined') {
                        isNew = true;
                    }

                    var accom = JSON.parse(JSON.stringify(this.state.accommodation[i]));
                    this.state.accommodation.splice(i, 1);

                    if (isNew) {
                        accom.AvailabilityCacheData = data[j];

                        ////if we have not already set the current offer code, lets update the default one
                        //if (this.state.currentOfferCode == null) {
                        //    this.state.currentOfferCode = accom.AvailabilityCacheData.DefaultRateID;
                        //}

                    }
                    else {
                        //now we need to join the new data with the old data
                        for (var k = 0; k < data[j].Rates.length; k++) {
                            var rate = _.find(accom.AvailabilityCacheData.Rates, { RateID: data[j].Rates[k].RateID });

                            if (typeof rate !== 'undefined') {
                                var deDupeRates = rate.Dates.concat(data[j].Rates[k].Dates);

                                //We only want to keep maximum two months at a time for performance 
                                if (deDupeRates.length >= 90 && (data[j].Rates[k].Dates.length > 30)) {
                                    this.state.currentAvailabilityRange = data[j];
                                }

                                deDupeRates = _.uniqBy(deDupeRates, function (e) {
                                    return e.Date;
                                });

                                deDupeRates.sort(function compare(a, b) {
                                    var dateA = moment(a.Date);
                                    var dateB = moment(b.Date);

                                    if (dateA.isSame(dateB)) { return 0; }
                                    if (dateA.isAfter(dateB)) { return 1; }
                                    if (dateA.isBefore(dateB)) { return -1; }
                                });

                                rate.Dates = deDupeRates;
                            }
                            else {
                                accom.AvailabilityCacheData.Rates.push(data[j].Rates[k]);
                            }

                        }
                    }
                    this.state.accommodation.push(accom);
                }
            }
        }
    },
    ProcessPMSResults: function (data) {
        var accom = this.GetCurrentAccommodation();

        if (accom != undefined)
        {
            accom.CurrentPMSResult = [];

            var proposedAllotment = null;
            var currentAllotment = null;
            var noTariffsAvailable = true;

            //if we are on the deal page, we only want to show the deals for the current offer code
            if (this.state.isOnDealPage) {
                for (var i = 0; i < data.AllAllotments.length; i++) {
                    if (data.AllAllotments[i].Offercode == this.state.currentOfferCode) {
                        accom.CurrentPMSResult.push(data.AllAllotments[i]);
                        noTariffsAvailable = false;
                    }
                }
            } else {
                //now we need to select the best price
                if (data.AllAllotments.length > 0) {
                    var lowestIndex = 0;

                    for (var i = 0; i < data.AllAllotments.length; i++) {

                        noTariffsAvailable = false;
                        accom.CurrentPMSResult.push(data.AllAllotments[i]);
                        if (data.AllAllotments[i].IsAvailable) {
                            if ((data.AllAllotments[i].Total < data.AllAllotments[lowestIndex].Total) || data.AllAllotments[lowestIndex].IsAvailable == false) {
                                lowestIndex = i;
                            }
                        }

                        if (this.state.currentOfferCode != null && this.state.currentOfferCode == data.AllAllotments[i].Offercode) {
                            currentAllotment = data.AllAllotments[i];
                        }
                    }

                    //TW: Checks if a deal has been previously selected. This way we can adjust number of guests but retain the deal they selected. 
                    //Otherwise we present the cheapest price.
                    if (this.state.currentOfferCode != null && this.state.currentOfferCode != data.AllAllotments[lowestIndex].Offercode) {
                        proposedAllotment = data.AllAllotments[lowestIndex];
                    } else {
                        this.state.currentOfferCode = data.AllAllotments[lowestIndex].Offercode;
                    }

                }

                //if the current allotment is unavailable, but there is another allotment which is available,
                //lets show the user that one instead.
                if (currentAllotment !== null && proposedAllotment !== null) {
                    if (currentAllotment.Offercode !== proposedAllotment.Offercode) {
                        //2019-11-07 MW - Remove requirement for the current allotment to be unavailable, to
                        //                always show the best price.
                        //if (!currentAllotment.IsAvailable && proposedAllotment.IsAvailable) {
                        if (proposedAllotment.IsAvailable) {
                            this.state.currentOfferCode = proposedAllotment.Offercode;
                        }
                    }
                }

                if (currentAllotment == null && proposedAllotment != null) {
                    this.state.currentOfferCode = proposedAllotment.Offercode;
                }
            }

            this.state.noTariffsAvailable = noTariffsAvailable;

            //Push result to data layer
            if (!this.state.isOnDealPage) {
                window.GoogleAnalyticsEcommerceEventBus.$emit('ACCOM_DATE_UPDATE', currentAllotment, this.GetCurrentAccommodation());
            }
        }

        if (this.state.quickBooking.ParkSelectionID != "")
        {
            this.GetCurrentAllotment();
        }
    },
    GetInitialAvailability: function (searchMode) {
        var self = this;
        self.SetPriceLoading();

        var accom = this.GetCurrentAccommodation();

        var request = {
            ParkID: accom.ParkID,
            StandardRateOnly: !this.state.isOnDealPage,
            StartDate: moment().startOf('month'),
        };

        // if we have an end date, we go to the end of that month, otherwise, we just use the end of the month for the start date
        if (!self.state.endDate) {
            request.EndDate = moment(request.StartDate).add(1, 'month').endOf('month').add(1, 'days'); // end of the next month
        }
        else {
            request.EndDate = moment(self.state.endDate).endOf('month').add(1, 'days'); // end of the month
            var newStartDate = moment(self.state.endDate).add(-1, 'months').startOf('month'); // start of the month prior
            request.StartDate = moment.max(request.StartDate, newStartDate); // make sure the start date is not earlier than the current month
        }

        request.StartDate = request.StartDate.format("YYYY-MM-DD");
        request.EndDate = request.EndDate.format("YYYY-MM-DD");
        
        if (this.state.currentOfferCode != null && this.state.currentOfferCode != undefined) {
            request.RateID = this.state.currentOfferCode;
        }

        $.ajax({
            type: 'GET',
            url: '/api/Booking/GetRates',
            contentType: 'application/json; charset=utf-8',
            data: request,
            success: function (response) {
                if (response.ResponseStatus == eHttpResponseStatus.Ok) {
                    self.ProcessAvailabilityCacheData(response.Results);
                    self.SetPriceFinishedLoading();
                } else {

                    self.SetPriceLoadingError();
                }
            },
            error: function (xhr, ajaxOptions, thrownError) {
                self.SetPriceLoadingError();
            }
        });
    },
    GetAvailability: function (request, success, error) {
        var self = this;
        request.StandardRateOnly = !this.state.isOnDealPage;
        
        if (this.state.currentOfferCode != null && this.state.currentOfferCode != undefined) {
            request.RateID = this.state.currentOfferCode;
        }

        $.ajax({
            type: 'GET',
            url: '/api/Booking/GetRates',
            contentType: 'application/json; charset=utf-8',
            data: request,
            success: function (response) {
                if (response.ResponseStatus == eHttpResponseStatus.Ok) {
                    self.ProcessAvailabilityCacheData(response.Results);

                    if (!!success) {
                        success();
                    }
                }
                else {
                    self.showPriceError();

                    if (!!error) {
                        error();
                    }
                }

            },
            error: function (xhr, ajaxOptions, thrownError) {
                if (!!error) {
                    error();
                }
            }


        });
    },

    SetPriceLoading: function () {
        this.state.priceLoading = true;
        this.state.canAddToCart = false;
        this.state.priceLoadError = false;

        this.state.loadingCounter++;
    },
    SetPriceFinishedLoading: function () {

        this.state.loadingCounter--;
        if (this.state.loadingCounter == 0) {
            this.state.priceLoading = false;
            this.state.canAddToCart = true;
            this.state.priceLoadError = false;
        }


        this.InitialQuantityCheck();
    },
    SetPriceLoadingError: function () {
        this.state.loadingCounter--;
        if (this.state.loadingCounter == 0) {
            this.state.priceLoading = false;
            this.state.canAddToCart = false;
            this.state.priceLoadError = true;
        }
    },

    PopulateEquipmentTypes: function () {
        var self = this;
        $.ajax({
            type: 'GET',
            url: '/api/Booking/GetEquipmentTypes',
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                self.state.EquipmentTypes = data.Equipment;
            },
            error: function (xhr, ajaxOptions, thrownError) {
                Common.ShowError("An unexpected error has occurred.")
            }
        });

    },
    prefillSelections: function () {
        var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
        if (cookie != "") {
            cookie = JSON.parse(cookie);

            if (!!cookie.Dates) {
                if (moment(cookie.Dates.start).isSameOrAfter(new Date(), 'day') && moment(cookie.Dates.end).isSameOrAfter(new Date(), 'day')) {
                    this.state.startDate = moment(cookie.Dates.start);
                    this.state.endDate = moment(cookie.Dates.end);

                    this.state.dataPrefilled = true;
                }
            }

            if (!!cookie.Guests) {
                this.state.adults = cookie.Guests.adults;
                this.state.children = cookie.Guests.children;
                this.state.infants = cookie.Guests.infants;

                //For quick booking, make sure we update the accommodation store values
                if (window.AccommodationStore != undefined)
                {
                    window.AccommodationStore.state.NumAdults = cookie.Guests.adults;
                    window.AccommodationStore.state.NumChildren = cookie.Guests.children;
                    window.AccommodationStore.state.NumInfants = cookie.Guests.infants;
                }

                this.state.dataPrefilled = true;
            }
        }
    },
    CheckBookingIsWithinCartAccommodationTimeframe: function (arrivalDate, departureDate)
    {
        //Cart accommodation start and end date
        var start1 = moment(arrivalDate).format("YYYY-MM-DD");
        var end1 = moment(departureDate).format("YYYY-MM-DD");

        //New booking attempt start and end date
        var start2 = this.state.startDate.format("YYYY-MM-DD");
        var end2 = this.state.endDate.format("YYYY-MM-DD");

        var datesWithinTimeframe = moment(start1).isSame(start2)|| moment(start2).isAfter(start1)
                                   && (moment(end1).isSame(end2) || moment(end2)).isBefore(end1);

        if (!datesWithinTimeframe)
        {
            datesWithinTimeframe = ((moment(start2).isAfter(start1) || moment(start2).isSame(start1)) && moment(start2).isBefore(end1))
                || ((moment(end2).isBefore(end1) || moment(end2).isSame(end1)) && moment(end2).isAfter(start1));

            if (!datesWithinTimeframe)
            {
                datesWithinTimeframe = (moment(start2).isSame(end1) || moment(end2).isSame(start1));
            }
        }

        return datesWithinTimeframe;
    },
    CheckNumberAvailable: function (accom)
    {
        var currentCart = window.CartStore.state.cartItems;
        var cartAccomRooms = 0;
        var maxNumberOfRooms = 0;
        var index = 0;

        if (window.BookingStore.state.quickBooking.AccommodationSelectionID != "")
        {
            for (var i = 0; i < this.state.accommodation.length; i++)
            {
                if (this.state.accommodation[i].AccommodationID == window.BookingStore.state.quickBooking.AccommodationSelectionID)
                {
                    index = i;
                }
            }
        }

        var PMSResultIndex = 0;

        if (this.state.accommodation[index].CurrentPMSResult.length > 1 && this.state.currentOfferCode !== null && this.state.currentOfferCode !== undefined) {
            //Get the index for the PMS result that matches the current offer (standard rate or deal)
            for (var i = 0; i < this.state.accommodation[index].CurrentPMSResult.length; i++) {
                if (this.state.accommodation[index].CurrentPMSResult[i].Offercode === this.state.currentOfferCode) {
                    PMSResultIndex = i;
                }
            }
        }

        if (this.state.accommodation[index].CurrentPMSResult[PMSResultIndex] != undefined) {
            var dailyAvailabilityLength = this.state.accommodation[index].CurrentPMSResult[PMSResultIndex].DailyAvailability.length;
            var featureFlagIsEnabled = window.featureFlags.BAPI_4027;
            if (featureFlagIsEnabled) {
                dailyAvailabilityLength = dailyAvailabilityLength - 1;
            }

            //Checks that we only add the maximum number of available accommodations to the cart
            for (var i = 0; i < dailyAvailabilityLength; i++) {
                if (i == 0) {
                    maxNumberOfRooms = this.state.accommodation[index].CurrentPMSResult[PMSResultIndex].DailyAvailability[i].RoomsAvailable;
                } else if (maxNumberOfRooms > this.state.accommodation[index].CurrentPMSResult[PMSResultIndex].DailyAvailability[i].RoomsAvailable) {
                    maxNumberOfRooms = this.state.accommodation[index].CurrentPMSResult[PMSResultIndex].DailyAvailability[i].RoomsAvailable;
                }
            }

            //Checks that we only add the maximum number of available accommodations to the cart
            for (var i = 0; i < currentCart.length; i++) {
                if (currentCart[i].AccommodationType != null) {

                    var cartAccomID = currentCart[i].TransactionLineItem.Booking.AccommodationID;
                    var arrivalDate = currentCart[i].TransactionLineItem.ArrivalDate;
                    var departureDate = currentCart[i].TransactionLineItem.DepartureDate;

                    if (accom.AccommodationID == cartAccomID) {

                        //Checks whether the accommodation in the customers cart is from the same timeframe / has dates that overlap with an existing booking in their cart
                        var WithinSameTimeframe = this.CheckBookingIsWithinCartAccommodationTimeframe(arrivalDate, departureDate);

                        //if within the same time period as other booking from same accommodation
                        if (WithinSameTimeframe) {
                            cartAccomRooms++;
                        }
                    }
                }
            }

            window.BookingEventBus.$emit("quantity-update", { quantity: maxNumberOfRooms, accommodationID: this.state.accommodation[index].AccommodationID });

            if (cartAccomRooms >= maxNumberOfRooms || maxNumberOfRooms == 0) {
                this.state.canAddToCart = false
                this.state.showMaxAccommodationError = true;
                return false;
            } else {
                this.state.showMaxAccommodationError = false;
                this.state.canAddToCart = true
                return true;
            }
        } else {
            return true;
        }

    },
    InitialQuantityCheck: function ()
    {
        var maxNumberOfRooms = 0;
        var index = 0;

        if (window.BookingStore.state.quickBooking.AccommodationSelectionID != "") {
            for (var i = 0; i < this.state.accommodation.length; i++) {
                if (this.state.accommodation[i].AccommodationID == window.BookingStore.state.quickBooking.AccommodationSelectionID) {
                    index = i;
                }
            }
        }

        if (this.state.accommodation[index].CurrentPMSResult[0] != undefined) {
            //Checks that we only add the maximum number of available accommodations to the cart
            for (var i = 0; i < this.state.accommodation[index].CurrentPMSResult[0].DailyAvailability.length - 1; i++) {
                if (i == 0) {
                    maxNumberOfRooms = this.state.accommodation[index].CurrentPMSResult[0].DailyAvailability[i].RoomsAvailable;
                } else if (maxNumberOfRooms > this.state.accommodation[index].CurrentPMSResult[0].DailyAvailability[i].RoomsAvailable) {
                    maxNumberOfRooms = this.state.accommodation[index].CurrentPMSResult[0].DailyAvailability[i].RoomsAvailable;
                }
            }

            window.BookingEventBus.$emit("quantity-update", { quantity: maxNumberOfRooms, accommodationID: this.state.accommodation[index].AccommodationID});
        }
    },
    addToCart: function () {
        var self = this;
        this.state.addingToCart = true;

        var accom = this.GetCurrentAccommodation();
        var allotment = this.GetCurrentAllotment();

        var accomHasAvailableRooms = this.CheckNumberAvailable(accom);

        if (accomHasAvailableRooms) {
            var req = {
                ArrivalDate: this.state.startDate.format("YYYY-MM-DD"),
                DepartureDate: this.state.endDate.format("YYYY-MM-DD"),
                ParkID: accom.ParkID,
                AccommodationID: accom.AccommodationID,
                Adults: this.state.adults,
                Children: this.state.children,
                Infants: this.state.infants,
                ChargeTypeID: this.state.currentOfferCode,
                SpecialOfferID: allotment.SpecialOfferID,
            };

            if (!req.AccommodationID) {
                req.AccommodationID = accom.AccommodationId;
            }


            if (accom.IsCabin === false || (accom.AccommodationType && accom.AccommodationType.toUpperCase() == "SITES")) {
                req.EquipmentType = this.state.equipment.EquipmentTypeID;
                req.EquipmentWidth = this.state.equipment.Width;
                req.EquipmentLength = this.state.equipment.Length;
                req.EquipmentUnitOfLength = this.state.equipment.Unit;
            }

            if (req.ParkID == undefined && window.BookingStore.state.quickBooking.ParkSelectionID != "") {
                req.ParkID = window.BookingStore.state.quickBooking.ParkSelectionID;
            }

            window.CartEventBus.$emit(window.CartEvents.ADD_BOOKING, req,
                function () {
                    self.state.addingToCart = false;
                }, function (err) {
                    self.state.addingToCart = false;
                    if (err) {
                        Common.ShowError(err);
                    }
                    else {
                        Common.ShowError("Unable to add to cart, please try again.");
                    }
                });
        } else
        {
            this.state.addingToCart = false;
        }

    },


};



;
Vue.component('booking-widget-chevron', {
    template: "#BookingWidgetChevronTemplate",
    props:
    {
        isQuickBooking: false,
    },
    data: function()
    {
        return {
            store: window.BookingStore
        }
    },
    computed: {
        showCheckInChevron: function () {
            if (this.store.state.isCheckIn) {
                if (this.isQuickBooking) {
                    $('.c-input-date__picker').css('margin-left', '0');
                    $('.c-input-date__picker').css('margin-right', 'auto');
                }
                return true;
            }
        },
        showCheckOutChevron: function () {
            if (!this.store.state.isCheckIn) {
                if (this.isQuickBooking)
                {
                    $('.c-input-date__picker').css('margin-left', 'auto');
                    $('.c-input-date__picker').css('margin-right', '0');
                }
                return true;
            }
        },
    },
    mounted: function ()
    {
      
    },
});
;
Vue.component('booking-widget-compare-deals-wrapper', {
    mixins:[MIXIN_BOOKING_WIDGET],
    data: function () {
        return {
            store: window.BookingStore,
        }
    },
    computed: {
        dealsToCompare: function () {
            return this.currentAccommodation.CurrentPMSResult;
        },
        
    },
    methods: {
        hideModal: function () {
            this.$parent.closeModal();
        },
    }
});;
Vue.use(AsyncComputed);

Vue.component('booking-widget-date-wrapper', {
    data: function () {
        return {
            store: window.BookingStore,
            availabilityLoading: false,
            isOpen: false,
            fadeCalendar: true,
            cleared: false,
            rangeDisabled: false,
            keepCalendarClosed: false,
            currentPage: {},
     
        }
    },
    props:
    {
        isQuickBooking: false,
    },
    mixins: [MIXIN_BOOKING_WIDGET],
    computed: {
        state: function () {
            return this.store.state;
        },
        availableDateRangesForWidget: function () {
            var start = moment(this.currentPage.year + "-" + this.currentPage.month + "-01", "YYYY-MM-DD");
            var end = moment(start).add(1, 'month').endOf('month');
            return this.getAvailableRangesForDateRange(start, end);
        },
        props: function () {
            var self = this;

            return {
                endSelected: function () {
                    self.$data.keepCalendarClosed = false;
                    if (self.CalendarOpen())
                    {
                        self.SwapChevrons(true);
                    } else
                    {
                        self.$refs.dateInput.openDatepicker();
                        self.SwapChevrons(true);
                    }

                },
                startSelected: function () {
                    //Used to ensure calendar opens when selecting check in input
                    self.$data.keepCalendarClosed = false;
                    if (self.CalendarOpen()) {
                        self.SwapChevrons(false);
                    } else {
                        self.$refs.dateInput.openDatepicker();
                        self.SwapChevrons(false);
                    }

                },
                ClearDates: this.ClearDates,
                DatesSelected: this.datesSelected,
                CheckoutAvailability: this.CheckoutAvailability,
                IsCheckIn: this.store.state.isCheckIn,
                SwapChevrons: this.SwapChevrons,
                FadeCalendar: this.$data.fadeCalendar,
                IsOpen: this.$data.isOpen,
                CloseDatepicker: this.closeDatepicker,
                showCheckInStyling: this.store.state.isCheckIn,
            };
        },
        chevronTransition: function ()
        {
            //Used to create the fade in / out effect on the booking widget
            if (this.store.state.chevronsSwapped) {
                this.store.state.chevronsSwapped = false;
                return true;
            } else
            {
                return false;
            }
        }
    },
    methods: {
        UpdateCookie: function (data) {
            //when we apply the filter, we want to store the data in a cookie
            var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
            if (cookie == "") {
                cookie = {};
            }
            else {
                cookie = JSON.parse(cookie);
            }

            cookie.Dates = data;
            CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));
        },
        CloseCalendar: function ()
        {
            if (this.$refs.dateInput.isDragging && this.$refs.dateInput.selectedDate != null)
            {
                this.$refs.dateInput.isDragging = false;
                var start = moment(this.$refs.dateInput.selectedDate.start)._d;
                var end = moment(this.$refs.dateInput.selectedDate.start).add(1, 'days')._d;

                this.disableRangeSelect(start, end);
            }

            var closeObject = document.getElementById('booking_calendar_close');

            if (closeObject)
            {
                closeObject.style.display = "none";
            }

            this.$data.isOpen = false;
            this.$refs.dateInput.closeDatepicker();
            this.$data.fadeCalendar = true;
        },
        ClearDates: function (clicked) {
            var self = this;
            self.store.clearDates();
            window.BookingEventBus.$emit("DATE-CHANGED");
            
            self.UpdateCookie(null);

            //If dates are cleared via the clear date button. We discard the saved adjustment date
            if (clicked)
            {
                this.disableRangeSelect();
                this.store.state.adjustmentDate = null;
                this.$data.cleared = true;
                if (!this.store.state.isCheckIn)
                {
                    this.SwapChevrons(null);
                }
                window.BookingStore.state.rangeSelected = false;
            }

            //we need to do this to give some time for the isFocused to get set false.
            setTimeout(function () {
                self.$refs.dateInput.isFocused = true;
            }, 200);
        },
        CheckoutAvailability: function () {
            Vue.nextTick(function () {
                var self = this;
                this.$('.c-day').unbind('click');
                this.$('.c-day').on('click', function (event) { self.window.BookingEventBus.$emit('day-clicked', event.target) });
                
                //TW: If we are using an ios device, treat a tap on a day in the calendar as a double tap.
                //We unbind mouseover events first as this tended to fire twice.
                $('.c-day').unbind('mouseover');
                $('.c-day').on('mouseover', function (event) {
                    var IsIOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);

                    if (IsIOS && self.toDateOnly) {
                        event.target.click();
                        toDateOnly = false;
                    }
                    else {
                        if (IsIOS && self.fromDateSelected) {
                            event.target.click();
                        }
                        self.fromDateSelected = !self.fromDateSelected;
                    }
                });
            });
        },
        //Re-enables range selection and disregards saved end date value
        enableRangeSelect: function () {
            //This disregards the end date of a selected range and re-starts the range selection functionality
            var self = this;
            var datePicker = self.$refs.dateInput.$refs.datepicker;
            var dateInput = self.$refs.dateInput;

            if (dateInput.selectedDate.start.toDateString() == this.store.state.adjustmentDate.toDateString()) {
                datePicker.$children[0].dragValue = { start: dateInput.selectedDate.start, end: moment(dateInput.selectedDate.start).add(1, 'days')._d };
                datePicker.$children[0].value.start = dateInput.selectedDate.start;
                datePicker.$children[0].value.end = null;
            }
            else if (dateInput.selectedDate.end.toDateString() == this.store.state.adjustmentDate.toDateString()) {
                datePicker.$children[0].dragValue = { start: dateInput.selectedDate.end, end: moment(dateInput.selectedDate.end).add(1, 'days')._d };
                datePicker.$children[0].value.start = dateInput.selectedDate.end;
                datePicker.$children[0].value.end = null;
            }
            dateInput.isDragging = true;
            window.DateFilterStore.state.rangeSelected = false;
        },
        //Disables range selection in the calendar
        disableRangeSelect: function (startDate, endDate) {
            var self = this;
            self.$nextTick(function () {
                var datePicker = self.$refs.dateInput.$refs.datepicker;
                var dateInput = self.$refs.dateInput;

                if (datePicker.dragValue != null && startDate != undefined && endDate != undefined) {
                    //Prevent calendar from entering range selection
                    datePicker.$children[0].dragValue = null;
                    datePicker.$children[0].value = { start: startDate, end: endDate };
                    self.$refs.dateInput.isDragging = false;
                    self.$refs.dateInput.selectedDate = {
                        start: startDate,
                        end: endDate
                    };
                } else {
                    datePicker.$children[0].dragValue = null;
                    datePicker.$children[0].value = null;
                    self.$refs.dateInput.isDragging = false;
                    self.$refs.dateInput.selectedDate = null;
                    self.SwapChevrons(false);
                }

                

                self.$forceUpdate();
            });
        },
        adjustStart: function (selectionEnd, adjustmentDate) {
            //Adjusts only the start date and keeps the end date unchanged
            var self = this;
            self.ClearDates();

            if (adjustmentDate.toDateString() != selectionEnd.toDateString()) {
                self.$refs.dateInput.selectedDate.start = adjustmentDate;
                self.$refs.dateInput.selectedDate.end = selectionEnd;
            } else
            {
                self.$refs.dateInput.selectedDate.start = adjustmentDate;
                self.$refs.dateInput.selectedDate.end = moment(selectionEnd).add(1, 'days')._d;
            }
            window.DateFilterStore.state.rangeSelected = true;
        },
        adjustEnd: function (selectionStart, adjustmentDate) {
            //Adjusts only the end date and keeps the start date unchanged
            var self = this;
            self.ClearDates();
            if (adjustmentDate.toDateString() != selectionStart.toDateString()) {
                self.$refs.dateInput.selectedDate.end = adjustmentDate;
                self.$refs.dateInput.selectedDate.start = selectionStart;
            }
            else
            {
                self.$refs.dateInput.selectedDate.end = moment(adjustmentDate).add(1, 'days')._d;
                self.$refs.dateInput.selectedDate.start = selectionStart;
            }
            window.DateFilterStore.state.rangeSelected = true;
        },
        adjustStartAfterEndCheckIn: function (adjustmentDate) {
            //If an invalid selection is made (either selecting a checkout date prior to your check in or vice versa) 
            //we make this the new start date and the end date defaults to the next day
            var self = this;
            self.ClearDates();
            self.$refs.dateInput.selectedDate.start = adjustmentDate;
            self.$refs.dateInput.selectedDate.end = moment(adjustmentDate).add(1, 'day')._d;
            window.DateFilterStore.state.rangeSelected = false;
        },
        applyRangeAdjustment: function () {
            //Checks that allow the date range to be adjusted once selected
            var self = this;
            var adjustmentDate = self.store.state.adjustmentDate;
            var selectionStart = null;
            var selectionEnd = null;

            if (self.$refs.dateInput.selectedDate != null) {
                selectionStart = self.$refs.dateInput.selectedDate.start;
                selectionEnd = self.$refs.dateInput.selectedDate.end;


                //Calculate number of nights staying for selection 
                //if greater than 27 nights we reset the range selected bool and the picker returns to range selection
                var a = moment(adjustmentDate);
                var b = moment(selectionStart);
                var c = moment(selectionEnd);

                var nightsToStart = (a.diff(b, 'days') * -1);
                var nightsToEnd = (a.diff(c, 'days'));

                if (nightsToStart < -27 || nightsToEnd < -27) {
                    window.BookingStore.state.rangeSelected = false;
                }

                //This determines the logic for whether we are editing a pre-existing range, and which date to edit (start or end)
                if (self.$refs.dateInput.selectedDate && selectionStart != null && selectionEnd != null && window.BookingStore.state.rangeSelected) {
                    if (!self.store.state.isCheckIn) {
                        if (adjustmentDate > selectionEnd)
                        {   
                            self.adjustStartAfterEndCheckIn(adjustmentDate);                        
                       
                            self.adjustEnd(selectionStart, null);                          
                            self.store.state.adjustedStart = true;
                            self.store.state.adjustedEnd = false;

                        }
                        else
                        {
                            self.adjustStart(selectionEnd, adjustmentDate);
                            self.store.state.adjustedStart = true;
                            self.store.state.adjustedEnd = false;
                        }
                    }
                    else {
                        if (adjustmentDate < selectionStart) {                      
                           self.adjustStartAfterEndCheckIn(adjustmentDate);                        
                            self.store.state.adjustedStart = true;
                            self.store.state.adjustedEnd = false;

                        }
                        else {
                            self.adjustEnd(selectionStart, adjustmentDate);
                            self.store.state.adjustedStart = false;
                            self.store.state.adjustedEnd = true;
                        }
                    }
                } else {
                    self.ClearDates();
                    if (!selectionEnd) {
                        self.$refs.dateInput.selectedDate.start = self.$refs.dateInput.$refs.datepicker.value.start;
                        self.$refs.dateInput.selectedDate.end = adjustmentDate;
                    } else {
                        self.$refs.dateInput.selectedDate.start = adjustmentDate;
                        self.$refs.dateInput.selectedDate.end = null;
                    }
                }
            }
        },
        GetMoreAvailability: _.debounce(function (obj) {
            var self = this;
            var startDate = moment(obj.year + "-" + obj.month + "-01", "YYYY-MM-DD");
            var endDate = moment(startDate).add(1, 'month').endOf("month").add(1, 'days');

            if (self.currentAccommodation != undefined)
            {
                var request = {
                    ParkID: self.currentAccommodation.ParkID,
                    StartDate: startDate.format("YYYY-MM-DD"),
                    EndDate: endDate.format("YYYY-MM-DD"),
                };

                if (request.ParkID != undefined)
                {   self.availabilityLoading = true;
                    self.store.GetAvailability(request, function () {
                        self.availabilityLoading = false;
                    }, function () {
                        Common.ShowError("Unable to retrieve availability.")
                        self.availabilityLoading = false;
                    });
                }
            }


        }, 750),
        FadeCalendar: function ()
        {
            //Controls the fade in/out effect for the calendar
            var self = this;
            if (!self.$data.fadeCalendar) {
                self.$data.fadeCalendar = true;
                setTimeout(function () {
                    self.$data.fadeCalendar = false;
                }, 230);
            } else {
                setTimeout(function () {
                    self.$data.fadeCalendar = false;
                }, 155);
            }
        },
        SwapChevrons: function (checkOut)
        {
            this.FadeCalendar();

            //Logic that determines if the chevron is positioned over the check-in or check-out input boxes
            //If checkOut is null, this means we've clicked a date, not one of the input fields
            if (!this.$refs.dateInput.isDragging && !(this.isDragging && checkOut != null))
            {
                if (this.CalendarOpen()) {
                    if (checkOut == true) {
                        this.store.state.isCheckIn = false;
                    } else if (checkOut == false && checkOut != null) {
                        this.store.state.isCheckIn = true;
                    }
                } else {
                    this.store.state.isCheckIn = true;
                }

                if (!window.BookingStore.state.rangeSelected && checkOut != null) {

                    if (CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES") != "") {
                        var cookie = JSON.parse(CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES"));

                        if (!(cookie.Dates != null && cookie.Dates.start != "" && cookie.Dates.end != "")) {
                            this.store.state.isCheckIn = true;
                        }
                    }

                } else if (!window.BookingStore.state.rangeSelected && checkOut == null) {
                    this.store.state.isCheckIn = !this.store.state.isCheckIn;
                    this.$data.keepCalendarClosed = true;
                }
                //The following two checks allows us to keep the calendar open when adjusting the start date, and simply swap chevrons to check out input
                else if (window.BookingStore.state.rangeSelected && checkOut == null && this.store.state.isCheckIn) {
                    this.store.state.isCheckIn = false;
                    this.FadeCalendar();
                    this.$data.keepCalendarClosed = false;
                } else if (window.BookingStore.state.rangeSelected && checkOut == null && !this.store.state.isCheckIn) {
                    this.store.state.isCheckIn = true;
                    this.FadeCalendar();
                    this.$data.keepCalendarClosed = true;
                }
            } else if(checkOut == null) {
                this.$data.keepCalendarClosed = true;
            }
        },
        CalendarOpen: function ()
        {
            if (this.$refs.dateInput && this.store.state)
            {
                return this.$refs.dateInput.showDatepicker;
            }
            return false;
        }
    },
    mounted: function () {
        var self = this;

        self.$nextTick(function () {
            self.CheckoutAvailability();

            if (CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES") != "") {
                if (CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES") != "") {
                    var cookie = JSON.parse(CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES"));

                    if (cookie.Dates != null && cookie.Dates.start != "" && cookie.Dates.end != "") {
                        this.store.state.rangeSelected = true;
                    }
                }
            }
        });

        //when the user navigates pages, we want to go and fetch the next month worth of availability
        self.$refs.dateInput.$refs.datepicker.$on('update:fromPage', function (obj) {
            if (!!obj) {
                //we set this here because even though we debounce the requests, we need to make sure the user cant quickly select a date.
                self.availabilityLoading = true;
                self.GetMoreAvailability(obj);

                self.currentPage = obj;
            }
            else {
                var m = new moment(); // use the current date if we have not been given a date
                var newObj = {
                    year: m.year(),
                    month: m.month() + 1, // moment uses a 0 (zero) index for month so we need to add one month
                }
                self.currentPage = newObj;
            }
        });
        
        self.$watch('$refs.dateInput.selectedDate', function (newVal, oldVal) {
            if (newVal != null) {
                if (newVal.start != null && newVal.end != null) {
                    var startMoment = moment(newVal.start);
                    var endMoment = moment(newVal.end);

                    if (self.store.state.startDate != null && self.store.state.endDate != null) {
                        if (self.store.state.startDate.isSame(startMoment) && self.store.state.endDate.isSame(endMoment)) {
                            return;
                        }
                    }

                    self.store.state.startDate = moment(newVal.start);
                    self.store.state.endDate = moment(newVal.end);
                    window.BookingEventBus.$emit("DATE-CHANGED");

                    self.UpdateCookie(newVal);
                    self.store.UpdatePrice();
                }
            }

        });

        window.BookingEventBus.$on("DATE-CHANGED", function () {
            this.$nextTick(function () {

                if (self.$refs.dateInput) {

                    if (self.state.startDate && self.state.endDate) {
                        self.$refs.dateInput.selectedDate = {
                            start: self.state.startDate.toDate(),
                            end: self.state.endDate.toDate()
                        };
                    }
                    else {
                        self.$refs.dateInput.selectedDate = null;
                    }

                    self.$forceUpdate();
                    self.CloseCalendar();
                }
            });
        });

        self.$watch('$refs.dateInput.isFocused', function () {
            //This is code checking if we have just 
            //selected a checkout date and if so, to keep the calendar closed.Otherwise we swap date inputs and re - open the calendar
            this.$nextTick(function () {
                if (self.store.state.adjustmentDate != null && self.store.state.rangeSelected && self.$data.keepCalendarClosed) {
                    self.CloseCalendar();
                } else
                {
                    self.isOpen = self.$refs.dateInput.isFocused || self.$refs.dateInput.isActive;
                    self.$data.store.state.bookingWidgetCalendarOpen = self.isOpen;
                }
            });
        });

        self.$watch('$refs.dateInput.isActive', function (newVal, oldVal) {
            self.isOpen = self.$refs.dateInput.isFocused || self.$refs.dateInput.isActive;
            self.$data.store.state.bookingWidgetCalendarOpen = self.isOpen;
        });

        if (this.state.startDate != null && this.state.endDate != null) {

            //we need to use the next tick otherwise the display goes all funky
            this.$nextTick(function () {
                self.$refs.dateInput.selectedDate = {
                    start: self.state.startDate.toDate(),
                    end: self.state.endDate.toDate()
                }

                window.BookingEventBus.$emit("DATE-CHANGED");
            });
        }

        //Listener for closing Calendar 
        document.getElementById('booking_calendar_close').addEventListener('click', function () {
            self.CloseCalendar();
        });

        //Listener for clearing dates on accommodation calendar
        window.BookingEventBus.$on("accommodation-calendar-cleared", function () {
            self.$data.cleared = true;
        });

        //Listener for date range adjustment functionality 
        window.BookingEventBus.$on('date-adjusted', function (data) {
            if (data == 'widget') {
                if (self.$refs.dateInput != undefined)
                {
                    var datePicker = self.$refs.dateInput.$refs.datepicker;

                    //This ensures we never reset the date range selection when we do have a previous date selection
                    if (datePicker.value != null) {
                        self.store.state.savedCalendarValue = datePicker.value;
                    } else {
                        if (!self.$data.cleared) {
                            datePicker.value = self.store.state.savedCalendarValue;
                            self.$refs.dateInput.selectedDate = self.store.state.savedCalendarValue;
                        } else
                        {
                            self.$data.cleared = false;
                        }
                    }
                    self.applyRangeAdjustment();

                    if (datePicker.value)
                    {
                        var startDate = datePicker.value.start;
                        var endDate = datePicker.value.end;
                    }

                    if (datePicker.dragValue)
                    {
                        var a = moment(datePicker.dragValue.start);
                        var b = moment(datePicker.dragValue.end);
                        var nights = (a.diff(b, 'days')) * -1;

                        if (nights > 27) {
                            self.enableRangeSelect();
                        }
                    }

                    //This ensures range selection is disabled if we have a stored date range
                    this.$nextTick(function () {
                        if (datePicker.dragValue != null && window.BookingStore.state.rangeSelected && startDate != null && endDate != null) {
                            self.disableRangeSelect(startDate, endDate);
                            self.$data.rangeDisabled = true;
                        }
                    });
                }
            }
        });
        
    },

});;
Vue.component('booking-widget-deposit-wrapper', {
  mixins: [MIXIN_BOOKING_WIDGET, MIXIN_MEMBERSHIP],
  data: function () {
    return {
      allotment: undefined,
    }
  },
  computed: {
    // This relies on an emit behaviour within the Booking.js file for selectedAllotment
    hasDeposit: function() {
      if (this.allotment != undefined) {
        return this.allotment.HasDeposit;
      } else {
        return false;
      }
    },
    totalDeposit: function () {
      if (this.allotment != undefined) {
        return this.allotment.DepositCost;
      } else {
        return 0;
      }
    }
  },
  mounted: function() {
    var self = this;

    window.BookingEventBus.$on('deposit-amount-update', function(data){
      self.allotment = data;
    });
  },
});;
Vue.use(AsyncComputed);

Vue.component('booking-widget-guest-wrapper', {
    props:
    {
        isQuickBooking: false,
    },
    data: function () {
        return {
            store: window.BookingStore,
            active: false,
        }
    },
    methods: {
        apply: function (e) {
            var self = this;

            if (this.$refs.adultInput != undefined)
            {
                var data = {
                    adults: this.$refs.adultInput.quantity,
                    children: this.$refs.childrenInput.quantity,
                    infants: this.$refs.infantInput.quantity,
                }

                //for quick booking we need to populate the accommodation guests as well
                if (this.isQuickBooking)
                {
                    window.AccommodationEventBus.$emit("guest-filter-update", data);
                }

                //when we apply the filter, we want to store the data in a cookie
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }

                cookie.Guests = data;
                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie));



                this.state.adults = data.adults;
                this.state.children = data.children;
                this.state.infants = data.infants;

                if (self.isQuickBooking && this.state.quickBooking.isPark) {
                    self.updateFilterPersonaScore();
                }
                else if (!self.isQuickBooking)
                {
                    self.updateFilterPersonaScore();
                }

                self.toggle();

                self.store.UpdatePrice();
            }

        },
        updateFilterPersonaScore: function () {
            var self = this;
            var url = "";

            /*Post activity for personalisation*/
            if (self.store.state.adults > 2) {
                url += "/api/Personalization/FilteredByGroup";
            }
            else if (self.store.state.children >= 1 || self.store.state.infants) {
                url += "/api/Personalization/FilteredByFamily";
            }
            else if (self.store.state.adults == 2 && self.store.state.children == 0 && self.store.state.infants == 0) {
                url += "/api/Personalization/FilteredByNomad";
            }

            if (url != "") {
                $.ajax({
                    type: 'POST',
                    url: url,
                    contentType: 'application/json; charset=utf-8',
                    success: function () {
                    },
                    error: function (xhr, ajaxOptions, thrownError) {

                    }

                });
            }
        },
        toggle: function () {
            var self = this;
            this.active = !this.active;
            var self = this;
            $('body').one('click', function () {
                //self.toggle();
            });

            if (this.active) {
                this.$refs.adultInput.quantity = this.state.adults;
                this.$refs.childrenInput.quantity = this.state.children;
                this.$refs.infantInput.quantity = this.state.infants;

                this.$nextTick(function () {
                    

                    $('body').one('click', function () {
                        //self.toggle();
                    });
                });
            }
        },
        close: function ()
        {
            //When we click off of guest
            var self = this;
            if (self.active)
            {
                this.apply();
            }
        },

    },
    computed: {
        guestTotal: function () {
            var guestString = "";
            adultCount = this.store.state.adults;
            childrenCount = this.store.state.children;
            infantCount = this.store.state.infants;

            if (adultCount > 0) {
                if (adultCount == 1) {
                    guestString += ", " + adultCount + " adult";
                }
                else {
                    guestString += ", " + adultCount + " adults";
                }

            }
            if (childrenCount > 0) {
                if (childrenCount == 1) {
                    guestString += ", " + childrenCount + " child";
                }
                else {
                    guestString += ", " + childrenCount + " children";
                }
            }
            if (infantCount > 0) {
                if (infantCount == 1) {
                    guestString += ", " + infantCount + " infant";
                }
                else {
                    guestString += ", " + infantCount + " infants";
                }
            }

            if (guestString.startsWith(", ")) {
                guestString = guestString.substring(2);
            }

            if (guestString == "") {
                return "Select guests"
            }

            return guestString;
        },
        state: function () {
            return this.store.state;
        }
    },
    mounted: function () {
        var self = this;
        var element = $('.c-booking-widget');
        var handler = element.on('click', function (e) {
            e.stopPropagation();
        });

        $(document).on('click', function (event) {
            self.close();
        });
    }

});;
Vue.component('booking-widget-price-display', {
    template: "#BookingWidgetPriceDisplayTemplate",
    mixins: [MIXIN_BOOKING_WIDGET, MIXIN_MEMBERSHIP],
    props:["allotment","availability-cache-data"],
    data: function () {
        return {
            store: window.BookingStore,
        }
    },
    computed: {
 
        price: function () {
            if (!this.isTotalPrice) {
                //this returns the first price as it should be returning "tonights" price
                return this.RoundPrice(this.store.GetCurrentAccommodation().AvailabilityCacheData.DefaultRate.Price);

            }
            else {
                if (this.allotment != undefined)
                {
                    return this.RoundPrice(this.allotment.Total);
                }
            }
            
        },
        dynamicSummaryString: function ()
        {
            if (this.store.state.startDate && this.store.state.endDate)
            {
                var a = moment(this.store.state.startDate._d);
                var b = moment(this.store.state.endDate._d);

                var children = this.store.state.children > 0 ? ", " + this.store.state.children + " children" : "";
                if (this.store.state.children == 1)
                {
                    children = children.replace("children", "child");
                }

                var infants = this.store.state.infants > 0 ? ", " + this.store.state.infants + " infants" : "";
                if (this.store.state.infants == 1) {
                    infants = infants.replace("infants", "infant");
                }

                var adults = this.store.state.adults == 1 ? this.store.state.adults + " adult" : this.store.state.adults + " adults";

                var nights = (b.diff(a, 'days'));

                var nightMessage = nights + " nights - ";

                if (nights == 1)
                {
                    nightMessage = nightMessage.replace("nights", "night");
                }

                return nightMessage + adults + children + infants; 
            } 
            return '';
        },
        discountPrice: function () {
            if (!this.isTotalPrice) {
                //this returns the first price as it should be returning "tonights" price
                return this.RoundPrice(this.store.GetCurrentAccommodation().AvailabilityCacheData.DefaultRate.DiscountPrice);
            }
            else {
                if (this.allotment != undefined)
                {
                    return this.RoundPrice(this.allotment.Total - this.allotment.MemberDiscount);
                }
            }
        },
        discountAmount: function () {
            return this.RoundDiscountPrice(this.allotment.Discount);
        },
        isDeal: function () {
            return this.isTotalPrice && this.allotment.IsSpecialRate;
        },
        isTotalPrice: function () {
            return !!this.allotment;
        },
        
        isMemberOnlyDeal: function () {
            //all deals are member only deals...
            return this.isDeal;
        },
        showMemberPrice: function () {
            return (this.isLoggedIn && !this.isHolidayPerksMember) || this.isMemberOnlyDeal;
        },
        memberPriceEqualToNonMember: function ()
        {
            return (this.discountPrice == this.price);
        },
    
        state: function () {
            return this.store.state;
        },
        
        membershipLevelClass: function () {
            if (this.isDeal) {
                if (this.allotment.MemberOnly) {
                    if (this.isVipPerksMember) { 
                        return "c-pricing__membership--vip";
                    }
                    return "c-pricing__membership--plus"; 
                }
                else {
                    return "c-pricing__membership--holiday"; 
                }
            }

            if (this.isVipPerksMember) {
                return "c-pricing__membership--vip";
            }
            return "c-pricing__membership--plus"; 
        },
        membershipLevelLogo: function () {

            if (this.isDeal) {
                if (this.allotment.MemberOnly) {
                    if (this.isVipPerksMember) {
                        return this.logos.vipPerks;
                    }
                    return this.logos.perksPlus;
                }
                else {
                    return this.logos.holidayPerks;
                }
            }

            if (this.isVipPerksMember) {
                return this.logos.vipPerks;
            }
            return this.logos.perksPlus; 

        },
        mounted: function ()
        {
        }
    },
});
;
Vue.component('booking-widget-responsive-price-wrapper', {
    mixins: [MIXIN_BOOKING_WIDGET],
    props:["is-quick-booking","search-mode"],
    data: function () {
        return {
            store: window.BookingStore,
            disableFreeMembership: window.featureFlags.BAPI_3685_disable_membership_messaging,
        }
    },
    computed: {
        props: function () {
            return this.$parent.props;
        },
        accommodationName: function ()
        {
            if (window.AccommodationStore != undefined)
            {
                var currentAccommodation = this.store.GetCurrentAccommodation();
                if (currentAccommodation != undefined) {
                    return currentAccommodation.AccommodationName;
                }
                else
                {
                    return "";
                }
            }
        },
        cartHasMembership() {
            const { cartItems } = window.CartStore.state;

            if (cartItems && cartItems.length > 0) {
                for (let i = 0; i < cartItems.length; i += 1) {
                    if (cartItems[i].CartItemTypeID === window.CartItemType.MEMBERSHIP) {
                        return true;
                    }
                }
            }

            return false;
        },
        priceDisplayed() {
            if (this.store.state.startDate != null && this.store.state.endDate != null
                && !this.store.state.priceLoading && !this.store.state.priceLoadError
                && !this.store.state.noTariffsAvailable && !this.selectedAllotment.UnavailableMessage
                && !this.store.state.isOnDealPage && !this.cartHasMembership) {
                return true;
            }

            return false;
        },
    },
    methods: {
        toggleResponsiveBookingWidget: function () {
            this.props.toggle();
      
            //Toggle header display
            var searchHeaderElement = document.getElementById('searchHeader');
            var headElements = document.getElementsByClassName('c-head-sticky');
            const banner = document.getElementById('accom-type-banner');

            banner.style.display = 'none';
            document.body.style.overflow = 'hidden';

            if (searchHeaderElement) {
                if (searchHeaderElement.classList.contains('search-header-no-display')) {
                    searchHeaderElement.classList.remove('search-header-no-display');
                } else {
                    searchHeaderElement.classList.add('search-header-no-display');
                }
            }

            if (headElements != null && headElements.length > 0) {
                for (let i = 0; i < headElements.length; i++) {
                    if (headElements[i].classList.contains('search-header-no-display')) {
                        headElements[i].classList.remove('search-header-no-display');
                    } else {
                        headElements[i].classList.add('search-header-no-display');
                    }
                }
            }
        }
    },
    mounted() {
        if (this.props.searchMode) {
            this.toggleResponsiveBookingWidget();
        }
    },
});
;
Vue.component('equipment', {
    mixins: [MIXIN_BOOKING_WIDGET],
    template: "#EquipmentTemplate",
    data: function () {
        return {
            store: window.BookingStore,
            equipmentUnitStore: window.eEquipmentUnitOfLength,
            realWidth: 0.00,
            realLength: 0.00,
        }
    },
    computed: {
        isMetres: function () {
            return this.store.state.equipment.Unit == this.equipmentUnitStore.Metres; //Metres
        },
        unit: function () {
            if (!this.isMetres) {
                return "ft";

            }
            else {
                return "m";
            }

        },
        equipment: function () {
            return this.store.state.equipment;
        },
        equipmentTypes: function () {
            return this.store.state.EquipmentTypes;
        },
        unitValues: function () {
            if (this.isMetres) {
                return this.store.state.UnitValuesMetres;
            }
            else {
                return this.store.state.UnitValuesFeet;
            }
        }
    },
    watch: {
        equipment: {
            handler: function () {
                this.checkforUpdate();
            },
            deep: true
        },
    },
    methods: {
        toggleUnits: function () {
            if (this.unit == "m") {
                this.store.state.equipment.Unit = 1;
                this.realWidth = this.realWidth / 0.3048;
                this.realLength = this.realLength / 0.3048;
            }
            else {
                this.store.state.equipment.Unit = 0;
                this.realWidth = this.realWidth * 0.3048;
                this.realLength = this.realLength * 0.3048;
            }

            if (this.realWidth > 0) {
                this.store.state.equipment.Width = Math.round(this.realWidth);
            }

            if (this.realLength > 0) {
                this.store.state.equipment.Length = Math.round(this.realLength);
            }
        },
        lengthChanged: function (event) {
            this.realLength = parseInt(event.target.value);
        },
        widthChanged: function (event) {
            this.realWidth = parseInt(event.target.value);
        },
        checkCookieForEquipment: function () {
            //see if we have a cookie to retrieve dates from
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie != "") {

                    cookie = JSON.parse(cookie);
                    if (!!cookie.EquipmentTypeID && !!cookie.EquipmentWidth && !!cookie.EquipmentLength) {
                        this.equipment.EquipmentTypeID = cookie.EquipmentTypeID;
                        this.equipment.Width = cookie.EquipmentWidth;
                        this.equipment.Length = cookie.EquipmentLength;
                    }
                }
            } catch (e) {
            }
        },
        checkforUpdate: _.debounce(function () {

            if (this.equipment.Width == null || this.equipment.Width == "") { return; }

            if (this.equipment.Length == null || this.equipment.Length == "") { return; }

            if (this.equipment.EquipmentTypeID == null || this.equipment.EquipmentTypeID == "") { return; }

            //when we apply the filter, we want to store the data in a cookie
            try {
                var cookie = CookieHelper.GetCookieValue(".BIG4_SEARCH_PREFERENCES");
                if (cookie == "") {
                    cookie = {};
                }
                else {
                    cookie = JSON.parse(cookie);
                }
                cookie.EquipmentTypeID = this.equipment.EquipmentTypeID;
                cookie.EquipmentWidth = this.equipment.Width;
                cookie.EquipmentLength = this.equipment.Length;

                CookieHelper.SetCookieValue(".BIG4_SEARCH_PREFERENCES", JSON.stringify(cookie), cookie.Dates.end);
            }
            catch (e) {
            }

            this.store.UpdatePrice();
        }, 500)
    },
    mounted: function () {
        this.checkCookieForEquipment();
    }
});
;
