function InitializePage(self) {
    self.carrierData = ko.observable();
    self.manufacturerData = ko.observable();
    self.featuredManufacturerData = ko.observable();
    self.modelData = ko.observable();
    self.conditionData = ko.observable();
    self.search = ko.observable('');


    self.selectedCarrier = ko.observable();
    self.selectedManufacturer = ko.observable();
    self.selectedModel = ko.observable();
    self.selectedCondition = ko.observable();
    self.tradeInPrice = ko.observable();
    self.tradeInPriceValue = ko.observable();

    self.carrierData({ "carriers": null });
    self.manufacturerData({ "manufacturers": null });
    self.featuredManufacturerData({ "featuredManufacturers": null });
    self.modelData({ "models": null });
    self.conditionData({ "conditions": null });

    self.selectedManufacturer(null);
    self.selectedCarrier(null);
    self.selectedModel(null);
    self.selectedCondition(null);
    self.tradeInPrice(null);
    self.tradeInPriceValue(null);
    self.pageSize = ko.observable("20");
    self.featuredPageSize = ko.observable("10");

    LoadCarriers(self);
    this.useanimation = function (elem) { if (elem.nodeType === 1) $(elem).hide().fadeIn('slow') }
}
ko.bindingHandlers.fadeVisible = {
    init: function (element, valueAccessor) {
        // Initially set the element to be instantly visible/hidden depending on the value
        var value = valueAccessor();
        $(element).toggle(ko.unwrap(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable
    },
    update: function (element, valueAccessor) {
        // Whenever the value subsequently changes, slowly fade the element in or out
        var value = valueAccessor();
        ko.unwrap(value) ? $(element).slideDown() : $(element).slideUp();
    }
};

$('input').keypress(function (event) {
    if (event.keyCode == 13) {
        event.preventDefault();
    }
});

function LoadCarriers(self) {     
    $.ajax({
        dataType: "json",
        method: "get",
        url: GetCarriersUrl

    }).done(function (returnObject) {
        self.carrierData({ "carriers": ko.toJS(returnObject) });
    });
}

function LoadGoToEvents(self) {
    self.goToCarriers = function () {
        self.search('');
        self.selectedManufacturer(null);
        self.selectedCarrier(null);
        self.selectedModel(null);
        self.selectedCondition(null);
        $("#btnNext").attr("disabled", true).css('background-color', '#C4CDE3').hide();
    };

    self.goToManufacturers = function (carrier) {
        self.selectedCarrier({ Id: carrier.Id, Name: carrier.Name });
        GoToManufacturers(self);
        $("#btnNext").attr("disabled", true).css('background-color', '#C4CDE3').hide();
    };

    self.goToManufacturersBc = function () {
        GoToManufacturers(self);
        $("#btnNext").attr("disabled", true).css('background-color', '#C4CDE3').hide();
    };

    self.goToModels = function (manufacturer) {
        self.selectedManufacturer({ Id: manufacturer.Id, Name: manufacturer.Name });
        GoToModels(self);
        $("#btnNext").attr("disabled", true).css('background-color', '#C4CDE3').hide();
    };

    self.goToModelsBc = function () {
        GoToModels(self);
        $("#btnNext").attr("disabled", true).css('background-color', '#C4CDE3').hide();
    };

    self.goToConditionsBc = function () {
        GoToConditions(self);
        $("#btnNext").attr("disabled", true).css('background-color', '#C4CDE3').hide();
    }
  
    self.goToConditions = function (model) {
        self.selectedModel({ Id: model.Id, Name: model.Name });
        GoToConditions(self);
        $("#btnNext").attr("disabled", true).css('background-color', '#C4CDE3').hide();
    }

    self.goToPrice = function (condition) {
        $("#btnNext").show();
        self.search('');
        self.selectedCondition({ Id: condition.Id, Name: condition.Name });
        self.tradeInPrice(GetTradeInPrice(self));
        
        $("#btnNext").attr("disabled", false).css('background-color', '#5C75B1');
        
        $("#btnPrevious").hide();
    };
}

function GoToManufacturers(self) {
   // $.parent("#TitleLabel").html("Select Manufacturer");
    $("#TitleLabel").html("Select Manufacturer");

    self.search('');
    self.manufacturerData({ "manufacturers": null });
    self.featuredManufacturerData({ "featuredManufacturers": null });
    self.modelData({ "models": null });
    self.selectedManufacturer(null);
    self.selectedModel(null);
    self.selectedCondition(null);

    $.ajax({
        dataType: "json",
        method: "get",
        url: GetManufacturesForSelectedCarrierUrl,

        data: { 'carrierId': self.selectedCarrier().Id }
    }).done(function (returnObject) {
        self.manufacturerData({ "manufacturers": ko.toJS(returnObject) });
    });

    $.ajax({
        dataType: "json",
        method: "get",
        url: GetFeaturedManufacturesForSelectedCarrierUrl,

        data: { 'carrierId': self.selectedCarrier().Id }
    }).done(function (returnObject) {
        self.featuredManufacturerData({ "featuredManufacturers": ko.toJS(returnObject) });
    });

  
};



function GoToModels(self) {
    self.search('');
    self.selectedModel(null);
    self.modelData({ "models": null });
    self.selectedCondition(null);
    $.ajax({
        dataType: "json",
        method: "get",
        url: GetModelsForSelectedManufactureUrl,

        data: { 'manufacturerId': self.selectedManufacturer().Id, 'providerId': self.selectedCarrier().Id }
    }).done(function (returnObject) {
        self.modelData({ "models": ko.toJS(returnObject) });
    });
};

function GoToConditions(self) {
    self.search('');
    self.selectedCondition(null);    
    self.conditionData({ "conditions": null });
    $.ajax({
        dataType: "json",
        method: "get",
        url: GetDeviceConditionsUrl

    }).done(function (returnObject) {
        self.conditionData({ "conditions": ko.toJS(returnObject) });
    });
}


function GetTradeInPrice(self) {
     
    self.conditionData({ "conditions": null });
    $.ajax({
        dataType: "json",
        method: "get",
        url: GetTradeInPriceUrl,
        data: { 'modelId': self.selectedModel().Id, 'providerId': self.selectedCarrier().Id, 'conditionId':self.selectedCondition().Id }
    }).done(function (returnObject) { 
        self.tradeInPriceValue(returnObject.price);
        return self.tradeInPrice(returnObject.message);        
    });
}

function LoadShowEvents(self) {
    self.showCarrierData = ko.computed(function () { return (self.selectedCarrier() == null) });
    self.showManufacturerData = ko.computed(function () { return (self.selectedCarrier() != null && self.selectedManufacturer() == null) });
    self.showModelData = ko.computed(function () { return (self.selectedModel() == null && self.selectedManufacturer() != null) });
    self.showConditionData = ko.computed(function () { return (self.selectedCondition()) == null && self.selectedModel() != null });
    self.showPrice = ko.computed(function () { return (self.selectedModel() != null && self.selectedCondition() != null) });
}

function LoadFilters(self) {
    self.filteredCarriers = ko.computed(function () {
        return ko.utils.arrayFilter(self.carrierData().carriers, function (rec) {
            return (rec.Name.toLowerCase().indexOf(self.search().toLowerCase()) > -1)
        });
    });


    self.filteredModels = ko.computed(function () {
        if (self.modelData() != null) {
                return new ko.utils.PagedObservableArray({
                    data:   ko.utils.arrayFilter(self.modelData().models, function (rec) {
                        return  (rec.Name.toLowerCase().indexOf(self.search().toLowerCase()) > -1)
                    }),
                    pageSize: self.pageSize()
            });
              
        }
    });


    self.filteredManufacturers = ko.computed(function () {
        if (self.manufacturerData() != null) {
            return new ko.utils.PagedObservableArray({
                data:  ko.utils.arrayFilter(self.manufacturerData().manufacturers, function (rec) {
                return (rec.Name.toLowerCase().indexOf(self.search().toLowerCase()) > -1)
                }),
                pageSize: self.pageSize()
            });

        }
    });

    self.filteredFeaturedManufacturers = ko.computed(function () {
        if (self.featuredManufacturerData() != null) {
            return new ko.utils.PagedObservableArray({
                data: ko.utils.arrayFilter(self.featuredManufacturerData().featuredManufacturers, function (rec) {
                    return (rec.Name.toLowerCase().indexOf(self.search().toLowerCase()) > -1)
                }),
                pageSize: self.featuredPageSize()
            });

        }
    });

    self.filteredConditions = ko.computed(function () {
        if (self.conditionData() != null) {
            return ko.utils.arrayFilter(self.conditionData().conditions, function (rec) {
                return (rec.Name.toLowerCase().indexOf(self.search().toLowerCase()) > -1);
            });
        }
    });
}

function goBack() {
    $("#breadcrumb").find("li:visible").eq(-2).find("a").eq(0).click();
}

ko.utils.PagedObservableArray = function (options) {
    options = options || {};
    if ($.isArray(options))
        options = { data: options };
    var
    //the complete data collection
    _allData = ko.observableArray(options.data || []),

    //the size of the pages to display
    _pageSize = ko.observable(options.pageSize || 10),

    //the index of the current page
    _pageIndex = ko.observable(0),

    //the current page data
    _page = ko.computed(function () {
        var pageSize = _pageSize(),
            pageIndex = _pageIndex(),
            startIndex = pageSize * pageIndex,
            endIndex = pageSize * (pageIndex + 1);

        return _allData().slice(startIndex, endIndex);
    }, this),

    //the number of pages
    _pageCount = ko.computed(function () {
        return Math.ceil(_allData().length / _pageSize()) || 1;
    }),

    //move to the next page
    _nextPage = function () {
        if (_pageIndex() < (_pageCount() - 1))
            _pageIndex(_pageIndex() + 1);
    },

    //move to the previous page
    _previousPage = function () {
        if (_pageIndex() > 0)
            _pageIndex(_pageIndex() - 1);
    };

    //reset page index when page size changes
    _pageSize.subscribe(function () { _pageIndex(0); });
    _allData.subscribe(function () { _pageIndex(0); });

    //public members
    this.allData = _allData;
    this.pageSize = _pageSize;
    this.pageIndex = _pageIndex;
    this.page = _page;
    this.pageCount = _pageCount;
    this.nextPage = _nextPage;
    this.previousPage = _previousPage;
    this.useanimation = function (elem) { if (elem.nodeType === 1) $(elem).hide().fadeIn('slow') }

};