/*
Fix for:
https://mootools.lighthouseapp.com/projects/2706/tickets/651-classtostring-broken-on-122-big-regression
*/
Class.Mutators.toString = Class.Mutators.valueOf = $arguments(0);

function buildConsoleObject(){	
	if (!window.console ){
	    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
	    window.console = {};
	    for (var i = 0; i < names.length; ++i){
			window.console[names[i]] = function() {};
		}
		names = null;
	}else if( Browser.Engine.webkit ){
	    var names = [ "debug", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
	    for (var i = 0; i < names.length; ++i){
			window.console[names[i]] = function() {};
		}
		names = null;		
	}
}

buildConsoleObject();

// process deeplinks
var hash = window.location.hash;
var configHash = "#productConfig";
var deepLinkHash = "#dl:";
if( window.location.hash.indexOf( deepLinkHash ) > -1 ){
	var configHashIndex = window.location.hash.indexOf( configHash )
	if( configHashIndex > -1 ) hash = window.location.hash.substr( 0, configHashIndex );
	window.location.href = "/" + hash.substr( 4, hash.length );
}

mop = { 
	
	ui: {},
	
	util: {
		
		getBaseURL: function(){
			return $(document).getElement("head").getElement("base").get("href");
		},

		getAppURL: function(){

			var appURLAppendClassName = mop.util.getValueFromClassName( "appUrlAppend", $(document).getElement("body").get("class") );

			var appUrlAppend;

			if( typeof appURLAppendClassName == "string" ){
				appUrlAppend = appURLAppendClassName + ".php/";
			}else{
				appUrlAppend = "";
			}

			// var appUrlAppend = ( appURLAppendClassName )? appURLAppendClassName + ".php/" : "";
			return mop.util.getBaseURL() + appUrlAppend;

		},
		
		/*
		 	Function: mop.util.stopEvent 
			Stops event bubbling, normally this is handled in each instance
			But this will serve as a nice shortcut given the verbosity needed to deal with Ie6 ( the whole return value conditional )
		*/
		stopEvent: function( e ){
			if( e && e.stop ){
				e.stop();
			}else if( e ){
				e.returnValue = false;
			}
		},

		/* Function: mop.util.getValueFromClassName
			Arguments: key {String}, aClassName {String} (space delimeted)
			Returns: {String} value
		*/
		getValueFromClassName: function( key, aClassName ){
			if(!aClassName) return;
			var classNames = aClassName.split( " " );
		//	console.log( "mop.util.getValueFromClassName ", classNames.join(", ") );
			var result = null;
			classNames.each( function( className ){
				if( className.indexOf( key ) == 0 ) result = className.split("-")[1];
			});
			return result;
		},

		toElement: function(){
			return this.element;
		},
	
		JSONSend: function( url, data, options, method ){
//			console.log( "JSONSend", url, data, options, method );
			if( options ){ 
				options.url = url;
			}else{
				options = { url: url };
			}
			if( method == "POST" || !method ){
				options.method = "post";
				new Request.JSON( options ).post( data );
			}else{
				options.method = "get";
				new Request.JSON( options ).get( data );
			}
		},
		
		validateEmail: function( value ){
			var emailRegex = /^[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i;
			return value.test( emailRegex );				
		},
		
		
		convertRot13 : function( aString ){
	    	return aString.replace( /[a-zA-Z]/g, function( c ){
	        	return String.fromCharCode( ( c <= "Z" ? 90 : 122 ) >= ( c = c.charCodeAt(0) + 13) ? c : c - 26 );
	    	});
		},
		
		decryptEmails: function(){
			var emailLinks = $$( ".emailLink a" );
			if( !emailLinks.length ) return;
			emailLinks.each( function( anElement ){
				anElement.set( "text", Rot13.convert( anElement.get( "text" ) ) );
				anElement.set( "href", Rot13.convert( anElement.get( "href" ) ) );
			});
		}
	}

};


krsp = {};
krsp.store = {};

krsp.store.ConfigurableProduct = new Class({

    initialize: function( config ){
//        this.config     = config;
        this.data       = config;
        this.config     = config.childProducts;
        this.taxConfig  = this.config.taxConfig;
        this.settings   = $$('.super-attribute-select');
        this.state      = new Hash();
        this.priceTemplate = this.config.template;
        this.prices     = config.prices;
        this.images     = this.getAllImages();
        this.curImage   = 0;
        this.settings.each(function(element){
            element.addEvent( "change", this.configure.bind(this));
        }.bind(this));

        // fill state
        this.settings.each(function(element) {
            // console.log( element.get( "id" ),  element.get( "id" ).replace( /[a-z]*/, '' ), this.config );
            var attributeId = element.get( "id" ).replace( /[a-z]*/, '');
            if( attributeId && this.config.attributes[attributeId]) {
                element.config = this.config.attributes[attributeId];
                element.attributeId = attributeId;
                this.state[attributeId] = false;
            }
        }, this );

        // Init settings dropdown
        var settings = this.settings,
            settingsLength = settings.length,
            childSettings = [];
        // console.dir(this.settings);
        for (var i = settingsLength - 1; i >= 0; i--) {
            var current = settings[i],
                prev = settings[i-1] || false,
                next = settings[i+1] || false


            // If the first one
            if (i === 0) {
                this.fillSelect(this.settings[i]);
            } else {
                this.settings[i].set("disabled", true);
            }

            if (childSettings.length) {
                // console.log("Childsettings");
                $(this.settings[i]).store("childSettings", childSettings);
            }
            $(this.settings[i]).store("prevSetting", prev);
            $(this.settings[i]).store("nextSetting", next);
            childSettings.push(this.settings[i]);
        }

        var hash = window.location.hash;
        if ( hash && window.location.hash.indexOf( configHash ) > -1 ) {
			var configHash = "#productConfig";
			var paramStrIndex = hash.indexOf( configHash );
            var paramsStr = hash.substr( paramsStr, configHash.length );
            this.values = paramsStr.toQueryParams();
            this.settings.each(function(element){
                var attributeId = element.attributeId;
                element.value = this.values[attributeId];
                this.configureElement(element);
            }.bind(this));
        }

        this.addToCartButton = $("addToCart");
        if( this.addToCartButton ) this.addToCartButton.addEvent("click", this.addToCart.bindWithEvent(this));
        
        // Init Previous / Next Images
        if (this.images.length > 1) {
            $$( ".imageNav" )[0].removeClass( "hidden" );
            $$("#previousImage, #nextImage").addEvent("click", this.nextPrevImage.bindWithEvent(this));
        } else {
            $$("#previousImage, #nextImage").addClass("hidden");
        }
    },

    nextPrevImage: function (e) {
        e.preventDefault();
        var images = this.images,
            nextImage;
        if (images.length > 1) {
            switch (e.target.id) {
                case "previousImage":
                    if (this.curImage > 0) {
                        nextImage = this.curImage - 1;
                    } else {
                        nextImage = images.length - 1;
                    }
                    break;
                case "nextImage":
                    if (this.curImage < (images.length - 1)) {
                        nextImage = this.curImage + 1;
                    } else {
                        nextImage = 0;
                    }
                    break;
                default:
                    break;
            }
        }
        if (typeof(nextImage) !== 'undefined' && nextImage !== this.curImage) {
            krsp.app.backgroundManager.loadProductBackground( null, images[nextImage].image);
            this.curImage = nextImage;
        }
    },

    getAllImages: function () {
        var images = this.data.images,
            all = [
                {
                    image: images.image,
                    small_image: images.small_image,
                    thumbnail: images.thumbnail
                }
            ];
        images.altImages.each(function (image, index) {
            all.push({image: image});
        });
        return all;
    },

    addToCart: function(e) {
        e.preventDefault();
		var productId = this.getProductId();
		if( !productId ){
			return false;
		}
//        var qty = 1;
		$( "cartAdditionStatus" ).addClass( "hidden" );
		// $( "addToCartSpinner" ).setStyle( "display", "block" );
		$( "addToCartSpinner" ).removeClass( "hidden" );
//		this.getProductId( e.target );
//        $("productOverlay").getElement( ".productAttributes" ).setStyle( "border", "1px #f00 solid" );
		console.log("productId", this.getProductId());
        var params = {
            "product_id": productId,
            "qty": $("qtyField").get( "value" )
        };
        mop.util.JSONSend("/shop/addToCart.php", params, {
            onComplete: krsp.app.onAddedToCart.bind( krsp.app )
        });
    },
    
    configure: function(event) {
        // console.log("configure");
        var element = event.target;
        this.configureElement(element);
        // console.log(":::::", this.state);
        // this.productId = this.getProductId( element );
    },

    configureElement: function(element) {
        var next = element.retrieve("nextSetting"),
            selected = element.getSelected()[0],
            value = selected.get("value");

        console.log("configureElement");
        if (value) {
            if (next) {
                this.fillSelect(next);
                element.erase("disabled");
                this.resetChildren(next);
            }
        } else {
            this.resetChildren(element);
        }
        this.reloadOptionLabels(element);
        this.reloadPrice();
        // Calculator.updatePrice();
    },

    allAttributesChosen: function () {
        return this.settings.every(function (setting, index, settings) {
            return setting.getSelected()[0].value !== "";
        });
    },

    getProductId: function() {
        var settings = this.settings;
        var config = this.config;
        var attributes = config.attributes;
        var productId;

        console.log(" getProductId", this.settings, config.attributes );
        //console.log(" settings", settings );

				if(!this.allAttributesChosen()){
                alert("Please choose product attributes (sizes, colors, etc... ) before adding to the cart.");
                return false;
				}
				//console.log('getting product id');
        settings.each(function (setting) {
            var selected = setting.getSelected()[0];
						//console.log('selected', selected);
            options = attributes[setting.attributeId].options;
            if (value = selected.get("value") ) {
								//loop through the options
								var nextProductIds = new Array();
                options.each(function (option, index, array) {
										//console.log('option ',option);
										if(option.id != value){
												console.log('This option is not selected');
											return;
										}
										
                    var products = option.products || false; //get all the products covered by this option
										console.log('products '+products);
                    if (products && productId) {
                        // Match productId (array or number) to a product
                        if (productId.constructor == Array) {
                             //console.log("isArray");
                            products.each(function (product, index) { //this basicalls asks
															console.log('product '+product);        //does the current array pf productIds
                                if (productId.contains(product)) {   //contain this particular product
																		//console.log('setting product id');
																		//in order to support more than 2 attributes
																		//this should be building an array to replace productId on the next iteration
																		console.log('product that matches '+product);
																		//productId = product;
                                    nextProductIds.include(product);
                                    return;
                                };
                            })
                        }
                    } else {
                        // Set the productId to products
												console.log('setting productId = products');
                        nextProductIds = products;
                        return;
                    }
                }, this);
								console.log('nextProductIds', nextProductIds);
								productId = nextProductIds;
            }
        }, this);
				//console.log('productid '+productId);
        return productId;
    },

    reloadOptionLabels: function( element ){
        var selectedPrice;
//          console.log( "reloadOptionLabels", element, element.getSelected()[0].retrieve( "config" ) );
        if( element.getSelected()[0].retrieve( "config" ) ){
            selectedPrice = parseFloat( element.getSelected()[0].retrieve( "config" ).price );
        }else{
            selectedPrice = 0;
        }
        for( var i = 0; i < element.getChildren( "options" ).length; i++ ){
            if( element.getSelected()[0].retrieve( "config" ) ){
                element.options[i].set( "text", this.getOptionLabel( element.getSelected()[0].retrieve( "config" ), element.getSelected()[0].retrieve( "config" ).price - selectedPrice ) );
            }
        }
    },

    resetChildren: function(element) {
        var childSettings = element.retrieve( "childSettings" );
        if (childSettings) {
            // console.log("resetChildren");
            for(var i=0;i< childSettings.length;i++){
                childSettings[i].set("selected", false);
                childSettings[i].set("disabled", true);
                if( element.config ){
                    this.state[element.retrieve( "config" ).id] = false;
                }
            }
        }
    },
    
    getOption: function (attributeId, optionId) {
        var options = this.config(attributeId);
//        console.log(options);
        return true;
    },

    getOptionsForProducts: function (attributeId, products) {
        var attributes = this.getAttributeOptions(attributeId);
        var optionsForProducts = [];
        attributes.each(function (attribute, index) {
            products.each(function (product, index) {
//                console.log(attribute.products, products, attribute.products.contains(product));
                if (attribute.products.contains(product)) {
                    optionsForProducts.push(new Element("option", {
                        "text": this.getOptionLabel(attribute, attribute.price),
                        "value": attribute.id
                    }));
                }
            }, this);
        }, this);
        return optionsForProducts;
    },

    fillSelect: function(element) {
//        console.log("fillSelect");
        var attributeId = element.get( "id" ).replace(/[a-z]*/, '');
        var options = this.getAttributeOptions(attributeId);
        
        // Clear it out
        this.clearSelect(element);
        // Add the first option
        element.options[0] = new Option(this.config.chooseText, '');
        
        var prev = element.retrieve("prevSetting");

        // If there are dependencies...
        if (prev) {
            var prevSelected = prev.getSelected()[0].value,
                prevAttrId = prev.get("id").replace(/[a-z]*/, ''),
                prevOptions = this.getAttributeOptions(prevAttrId);
            
            prevOptions.each(function (option, index) {
                if (option.id == prevSelected) { //if this is the option that was selected
                    var optionElements = this.getOptionsForProducts(attributeId, option.products);
                    optionElements.each(function (optionElement) {
                        element.adopt(optionElement);
                    })
                };
            }, this);
        } else { // No dependencies
            options.each(function (option, index) {
//                console.log(option);
                element.adopt(new Element("option", {
                    "text": this.getOptionLabel(option, option.price),
                    "value": option.id
                }));
                element.getChildren("option")[index].store("config", options[index]);
            }, this);
        };
        element.erase("disabled");
    },

    getOptionLabel: function(option, price){
        var price = parseFloat(price);
        if (this.taxConfig.includeTax) {
            var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
            var excl = price - tax;
            var incl = excl*(1+(this.taxConfig.currentTax/100));
        } else {
            var tax = price * (this.taxConfig.currentTax / 100);
            var excl = price;
            var incl = excl + tax;
        }

        if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
            price = incl;
        } else {
            price = excl;
        }

        var str = option.label;
        if (price) {
            if (this.taxConfig.showBothPrices) {
                str += ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
            } else {
                str+= ' ' + this.formatPrice(price, true);
            }
        }
        return str;
    },

    formatPrice: function(price, showSign){
        var str = '';
        price = parseFloat(price);
        if (showSign) {
            if (price < 0) {
                str += '-';
                price = -price;
            } else {
                str+= '+';
            }
        }

        var roundedPrice = (Math.round(price*100)/100).toString();

        if (this.prices && this.prices[roundedPrice]) {
            str+= this.prices[roundedPrice];
        } else {
            str+= this.priceTemplate.substitue( { price: price.toFixed(2) } );
        }
        return str;
    },

    clearSelect: function(element){
        for(var i=element.options.length-1;i>=0;i--){
            element.remove(i);
        }
    },

    getAttributeOptions: function(attributeId){
        if( this.config.attributes[attributeId] ){
            return this.config.attributes[attributeId].options;
        }
    },

    reloadPrice: function(){

        var price = 0;

        for(var i=this.settings.length-1;i>=0;i--){
            var selected = this.settings[i].getSelected()[0]; //[this.settings[i].selectedIndex];
            if( selected.retrieve( "config" ) ){
                price += parseFloat( selected.retrieve( "config" ).price );
            }
        }

        // console.log( ":::", price );

        return price;

        if($('product-price-'+this.config.productId)){
            $('product-price-'+this.config.productId).innerHTML = price;
        }
        this.reloadOldPrice();
    },

    reloadOldPrice: function(){
        if ($('old-price-'+this.config.productId)) {
            var price = parseFloat(this.config.oldPrice);
            for(var i=this.settings.length-1;i>=0;i--){
                var selected = this.settings[i].options[this.settings[i].selectedIndex];
                if( selected.retrieve( "config" ) ){
                    price+= parseFloat( selected.retrieve( "config" ).price );
                }
            }
            if (price < 0) { price = 0; }
            price = this.formatPrice(price);
            if ($('old-price-' + this.config.productId)) {
                $('old-price-' + this.config.productId).innerHTML = price;
            }
        }
    }
});

krsp.App = new Class({

	store: null,
	
	/* flag: on first run we want the image to start at 0,0, and load the high res version on load instead of at the end of slidein */
	isFirstRun: true,

	/* helps us keep track */
	activeNavItem: null,
	activeSubNavItem: null,
	
	thumbNav: null,

	/* info panes */
	content: null,
	productOverlay: null,

	/* persistent json request so we can cancel it when we issue another one for section change / page load */
	jsonRequest: null, 
	
	/* announcement list stuff */
	subscribeLink: null,
	
	/* add to cart link */
	addToCartLink: null,
	
	/* query the number of items in cart */	
	itemsInCartLink: "itemsInCart.php",
	
	dir: 1,
	
	getStoreURL: function(){
		return $( "storeURL" ).get( "value" );
	},
	
	initialize: function(){
	
//		console.log( this.toString(), "initialized" );
		this.content = $( document.body ).getElement( ".content" );
		this.productOverlay = $( document.body ).getElement( "#productOverlay" );
		this.initNav();
		if( $( document.body ).get( "id" ) == "collection" ){
			this.collectionNav = new krsp.Collection( $( document.body ).getElement(".thumbNav"), this );
		};
		this.subscribeLink = $( "subscribeLink" ).addEvent( "click", this.onSubscribeLinkClicked.bindWithEvent( this ) );
		this.wireContactForm();
		this.getItemsInCart();
		this.getItemsInCart.periodical( 60000, this );			
		this.backgroundManager = new mop.ui.BackgroundManager( this );

		if( window.location.href.indexOf( ".com/store/" ) > -1 ){
			//on static page ( deeplink ) hit...
			// is product or not?
			try{
//				console.log( "PRODUCTDATA", productData, $( "productContent" ) );
				var productContents = $("productContent").dispose().get("html");
				this.transition  = "horizontal";
				var json = { response: { data: productData, html: productContents } };
				this.onProductReceived( json );							
			}
			catch( error ){
			    console.log( error );
				//is not product
				//this is the same as the other else statement following it, which likely means the wrapping if should change, but for now this will have to do.
				var img = $( document.body ).getElement( ".bgImage" );
				var lSrc = img.get( "src" );
				var hSrc = img.get( "alt" );
				img.destroy();
				img = null;
				delete img;
				this.backgroundManager.loadPageBackground( lSrc, hSrc, this.dir );				
			}
			if( $("thumbNav") ) this.thumbNav = new krsp.store.ProductThumbNav( $( "thumbNav" ).dispose(), this );
		}else{
			var img = $( document.body ).getElement( ".bgImage" );
			var lSrc = img.get( "src" );
			var hSrc = img.get( "alt" );
			img.destroy();
			img = null;
			delete img;
			this.backgroundManager.loadPageBackground( lSrc, hSrc, this.dir );
		}

	},	
	
	wireContactForm: function(){
		this.contactForm = $( document.body ).getElement( ".contactForm" );
		if( this.contactForm ){
			var submitButton = this.contactForm.getElement( "input[type='submit']" ).addEvent( "click", this.submitContactForm.bindWithEvent( this ) );
		}
	},
	
	submitContactForm: function( e, submitHref ){
		mop.util.stopEvent( e );

		var name = $( "contact_name" ).get( "value" );
		var email = $( "contact_email" ).get( "value" )
		var subject = $( "contact_subject" ).get( "value" )
		var message = $( "contact_body" ).get( "value" )
		
		var errors = [];
		
		if( name == "" ){
			errors.push( "Please fill out your name." );
		}
		
		if( !mop.util.validateEmail( email ) ){
			errors.push( "Please enter a valid email." );
		}
		
		if( message == "" ){
			errors.push( "Please fill out a message before submitting the form." );
		}
		
		if( errors.length > 0 ){
			alert( "There are the following problems with your submissions:\n" + errors.join("\n") );
			return;
		}
		
		this.contactSpinner = new Spinner( null, { "message": "one moment please..." } );
		this.contactSpinner.show();
		
		var postObject = {
			name: name,
			email: email,
			subject: subject,
			message: message
		};
		var url = mop.util.getAppURL() + this.contactForm.getElement( "form" ).get( "action" );
		mop.util.JSONSend( url, postObject, { method: "post", onComplete: this.onContactFormSubmitted.bind( this ) });
	},
	
	onContactFormSubmitted: function( response ){
		try{
			if( !response.error ){
				this.contactForm.set( "html", "<div class='message success'>" + response.message + "</div>" );
			}else{
				this.contactForm.set( "html", "<div class='message error'>" + response.message + "</div>" );
			}
		}
		catch( error ){
			this.contactForm.set( "html", "<div class='message error'>" + error + "</div>" );			
		}
		this.contactSpinner.hide.delay( 500, this.contactSpinner );
	},
	
	getItemsInCart: function(){
		var url = this.getStoreURL() + this.itemsInCartLink;
		mop.util.JSONSend( url, null, { onComplete: this.onItemsInCartResponse.bind( this ) } );		
	},
	
	onItemsInCartResponse: function( response ){
		try{
			if( !response.error ){
				var cartLink = $( "viewCartLink" );
				if( cartLink ) cartLink.set( "text", "View Cart (" + response.summary + " Items)" );
				if( response.summary  && $( "cartButtons" ) ) $( "cartButtons" ).reveal();
			}else{
				console.log( response );
			}			
		}
		catch( error ){
			console.log( error );
		}
	},

	onSubscribeLinkClicked: function( e ){
		mop.util.stopEvent( e );
		var emailAddress = $( "newsletter" ).get( "value" );
		var mailingList = $( "mailingList" );
		if( mop.util.validateEmail( emailAddress ) ){
			var url = mailingList.getElement( "form" ).get( "action" )  + $( "mailingList" ).toQueryString();
			mailingList.getElement( ".form" ).dissolve();
			mailingList.getElement( ".success" ).reveal();
			mop.util.JSONSend( url, { "email": emailAddress }, { onSuccess: this.onSubscriptionResponse.bind( this ) } );
		}else{
			alert( "Invalid email address. Please enter a valid email address." );
			return false;
		}
	},

	onSubscriptionResponse: function( ){
//		console.log( "onSubscriptionResponse", $A( arguments ) );
	},
	
	toString: function(){
		return "[ object, krsp.App ]";
	},
	
	swapPageContent: function( contentHTML ){
		if( !this.content ) return;
		this.content.set( "reveal", { duration: 350, transition: 'linear', onComplete: this.revealContent.delay( 500, this, contentHTML ) } );
		this.content.dissolve();
	},
	
	swapProductInfo: function( productInfo ){
		if( !this.productOverlay ) return;
//		console.log( this.toString(), "swapProductInfo", productInfo, productInfo.html );
		this.productOverlay.empty();
		this.productOverlay.set( "html", productInfo.html );
		this.productOverlay.set( "reveal", { duration: 350, transition: 'linear', mode: "horizontal", onComplete: this.revealProductOveraly.bind( this, productInfo ) } );
		this.productOverlay.dissolve();
	},
	
	hideProductOverlay: function(){
		if( !this.productOverlay ) return;
		this.productOverlay.set( "reveal", { duration: 350, transition: 'linear', onComplete: $empty } );
		this.productOverlay.dissolve();			
	},

	revealProductOveraly: function( productInfo ){
		this.addToCartButton = $( "addToCart" );
		if( this.addToCartButton ) this.addToCartLink = this.addToCartButton.get( "href" );
		
//				console.log( "revealProductOveraly", productInfo );
        
        		// if inventory > 0 then do up pulldowns and add to cart... otherwise
//        if not in stock kill add to cart button, replace with not in stock message
        if( productInfo.data.inventory.is_in_stock.toInt() > 0 ){
        }else{
            this.productOverlay.getElement( ".productAttributes" ).empty();
            this.productOverlay.getElement( ".productAttributes" ).adopt( new Element( "h3", { "text": "Out of Stock" }) );
            this.addToCartButton.destroy();
        }
        
		this.productOverlay.set( "reveal", { duration: 350, transition: 'linear', onComplete: $empty } );
		this.productOverlay.reveal();
	
	},
	
	hideContent: function(){
//		console.log( "hideContent", this.toString() );
		if( this.content ){
			this.content.set( "reveal", { duration: 350, transition: 'linear', onComplete: $empty } );
			this.content.dissolve();	
		}
	},
	
	revealContent: function( contentHTML ){
		this.content.set( "html", contentHTML.get("html") );
		this.content.set( "reveal", { duration: 350, transition: 'linear', onComplete: $empty } );
		this.wireContactForm();
		this.content.reveal();
	},
	
	initNav: function(){
		this.links = $( "nav" ).getChildren( "li" );
		this.links.each( function( aNavItem, navItemIndex ){
            // console.log("------------------", aNavItem.getElement( "a" ).get( "text" ) );
			if( aNavItem.hasClass("active") ) this.setActiveNavItem( aNavItem );

			if( !aNavItem.hasClass( "ajaxBypass" ) ){

				aNavItem.addEvent( "click", this.onPageLinkClicked.bindWithEvent( this, aNavItem ) );
				aNavItem.store( 'index', navItemIndex );
				
				if( aNavItem.getElement( ".subnav" ) ){

					aNavItem.addEvent( "mouseenter", this.expandsubnav.bindWithEvent( this, aNavItem ) );
					aNavItem.addEvent( "mouseleave", this.collapsesubnav.bindWithEvent( this, aNavItem ) );
					aNavItem.store( 'subnavReveal', new Fx.Reveal( aNavItem.getElement( ".subnav" ), { duration: 300 } ) );
	
					this.activeSubnavItem = null;
	
					var subnavLinks = aNavItem.getElements( ".subnav>li" );
					
					subnavLinks.each( function( subnavLink, subnavItemIndex ){

                        // console.log( "::", subnavLink, subnavLink.hasClass( 'ajaxBypass' ) );
    
                        if(!subnavLink.hasClass("ajaxBypass")){

                            // console.log( "1) ",subnavLink.getElement( "a" ).get('text') );
                            
    						subnavLink.store( "parentNavItem", aNavItem );
    						subnavLink.store( "parentIndex", navItemIndex );
    						subnavLink.store( "index", subnavItemIndex );
    						subnavLink.addEvent( "click", this.onProductCategoryClicked.bindWithEvent( this, [ aNavItem, subnavLink ] ) );

                        }else{
                                // console.log( "<<<<<<<<<" );
                                // console.log( "1) ",subnavLink.getElement( "a" ).get('text') );
        						subnavLink.addEvent( "click", function(){ window.location.href = subnavLink.getElement( "a" ).get( "href" ); } );
                                
                        }
	
					}.bind( this ) );
				}

			}
		}, this );
	},

	onPageLinkClicked: function( e, aNavItem ){
		mop.util.stopEvent( e );
		if( aNavItem == this.activeNavItem ||  aNavItem.getElement( "a" ).hasClass( "shop" ) ) return;
		this.hideProductOverlay();
		this.transitionOrientation = "vertical";

		this.dir = 1
		this.dir = ( this.activeNavItem && this.activeNavItem.retrieve( "index" ) > this.activeNavItem.retrieve( "index" ) ) ? 1 : -1;
		
		var anchor = aNavItem.getElement( "a" );
		var href = anchor.get( "href" );
	    if( href ){	        
    		var insertionPoint = href.indexOf( ".com/" );
    		var path = href.substr( insertionPoint , href.length );
    		window.location.hash = "dl:" + path	+ anchor.get( "text" );
	    }
		if( this.activeSubnavItem ){
			this.activeSubnavItem.getElement( "a" ).removeClass( "active" );
			this.activeSubnavItem = null;
		}
		var url = "ajax/" + e.target.get( "href" );
		var onCompleteCallback = this.onPageInfoReceived.bind( this );
		$$( "#nav a .active").removeClass( "active" );
		this.setActiveNavItem( aNavItem );
		this.backgroundManager.spinner.show();
		if( this.jsonRequest ) this.jsonRequest.cancel();
		this.jsonRequest = mop.util.JSONSend( url, null, { onComplete: onCompleteCallback } );
	},
	
	onProductCategoryClicked: function( e, aNavItem, aSubnavItem ){
//		console.log( "onProductCategoryClicked", aSubnavItem, this.activeNavItem );
		mop.util.stopEvent( e );
		
//		this.hideContent();
		this.hideProductOverlay();
		
		var anchor = aSubnavItem.getElement( "a" );
		var href = anchor.get( "href" );
		var insertionPoint = href.indexOf( "store/" );
		var path = href.substr( insertionPoint, href.length );
		window.location.hash = "dl:"+path + anchor.get( "text" );
		
		if( aSubnavItem == this.activeSubnavItem ) return;
		if( this.activeSubnavItem ){
			this.activeSubnavItem.getElement( "a" ).removeClass( "active" );
			this.oldActiveSubnavItem = this.activeSubnavItem;
		}                         
		this.activeSubnavItem = aSubnavItem;
		aSubnavItem.getElement( "a" ).addClass( "active" );
		this.transitionOrientation = "vertical";
		var url = "ajax/" + e.target.get( "href" );
		var onCompleteCallback = this.onProductCategoryReceived.bind( this );
		this.setActiveNavItem( aSubnavItem.retrieve( "parentNavItem" ), url, onCompleteCallback );

		this.backgroundManager.spinner.show();
		if( this.jsonRequest ) this.jsonRequest.cancel();
		this.jsonRequest = mop.util.JSONSend( url, null, { onComplete: onCompleteCallback } );

	},
	
	onAddedToCart: function( response ){
		try {
			$("addToCartSpinner").addClass("hidden");
			if ( response.error ) {
				$("cartAdditionStatus").set( "text", "Awww hold up. There was a problem adding to the cart. \nERROR: " + response.error.message ).reveal();
			} else {
				if (response.summary) {
					$("cartAdditionStatus").set( "text", "Item successfully added." ).removeClass("hidden");
				    $( "viewCartLink" ).set( "text", "View Cart (" + response.summary + " Items)" );
                    $( "cartButtons" ).reveal();
				}
			}
		}
		catch( error ){ 
			console.log( "Error in " + this.toString() + " onAddedToCart \n\n " + error + "\n\n" + $A( arguments ) );
		}
	},
	

	setActiveNavItem: function( aNavItem ){
		if( this.thumbNav )	this.thumbNav.hide( true );
		if( this.activeNavItem ){
			this.oldActiveNavItem = this.activeNavItem;
			this.activeNavItem.getElement( "a" ).removeClass( "active" );
		};
//		console.log( "ANAVITEM" + aNavItem.getElement( "a" ) );
		aNavItem.getElement( "a" ).addClass( "active" );
		this.activeNavItem = aNavItem;
		if( this.oldActiveNavItem ) this.collapsesubnav( null, this.oldActiveNavItem );

	},

	expandsubnav: function( e, aNavItem ){
		if( e ) mop.util.stopEvent( e );
		aNavItem.retrieve( "subnavReveal" ).reveal();
	},
	
	collapsesubnav: function( e, aNavItem ){
//		console.log( "collapsesubnav", this.currentSection, aNavItem.getElement( "a" ).get( "text" ).toLowerCase() );
		if( e ) mop.util.stopEvent( e );
		if( this.activeNavItem != aNavItem ){
			aNavItem.removeClass("active");
			if( aNavItem.retrieve( "subnavReveal" ) ) aNavItem.retrieve( "subnavReveal" ).dissolve();
		}
	},
	
	onPageInfoReceived: function( json ){
		try{
//			console.log( this.toString(), "onPageInfoReceived", json, this.dir );
			var responseHTML = Elements.from( json.response, true );
			var img = responseHTML[1];
			var lSrc = img.get( "src" );
			var hSrc = img.get( "alt" );
			var contents = responseHTML[0];
			this.swapPageContent( contents );
			this.hideProductOverlay();
			this.backgroundManager.loadPageBackground( lSrc, hSrc, this.dir );			
		}
		catch( error ){
			console.log( error );
		}
	},
	
	onProductCategoryReceived: function( json ){
		try{
		    if( this.collectionNav ){
		        this.collectionNav.element.dissolve( { onComplete:  this.collectionNav.destroy.bind( this.collectionNav ) } );
		        this.collectionNav = null;
            }
//			console.log( this.toString(), "onProductCategoryReceived", json.response );
			var responseHTML = Elements.from( json.response, true );
			var thumbNavHTML = responseHTML[1];
			if( this.thumbNav ){
				this.thumbNav.reload( thumbNavHTML );
			}else{
				this.thumbNav = new krsp.store.ProductThumbNav( thumbNavHTML, this );
			}
			var img = responseHTML[2];
			var lSrc = img.get( "src" );
			var hSrc = img.get( "alt" );
			var contents = responseHTML[0];
			this.swapPageContent( contents );
			this.hideProductOverlay();
			this.backgroundManager.loadPageBackground( lSrc, hSrc, this.dir );			
		}			
		catch( error ){
			console.log( error );
		}
	},

	getProduct: function( url ){
//		console.log( "getProduct", url );
		this.transition  = "horizontal";
		mop.util.JSONSend( url, null, { onComplete: this.onProductReceived.bind( this ) } );
	},

	onProductReceived: function( json ){
//		console.log( "onProductReceived", json.response );
		this.swapProductInfo( json.response );

        var product = new krsp.store.ConfigurableProduct(json.response.data);
		//var product = new krsp.store.ConfigurableProduct( json.response.data.childProducts );
		this.hideContent();
		this.backgroundManager.loadProductBackground( json.response.data.images.small_image, json.response.data.images.image );
	},
	
	destroy: function(){
		try{
			if( this.store ) this.store.destroy();
			this.jsonRequest.cancel();
			this.productOverlay = null;
			this.section = null;
			this.sectionIndex = null;
			this.store = null;
			this.jsonRequest = null;
			delete this.productOverlay;
			delete this.section;
			delete this.sectionIndex;
			delete this.store;
			delete this.jsonRequest;		
		}
		catch( error ){
			console.log( "Error in " + this.toString() + " delete \n\n " + error.message );
		}
	}

});

mop.ui.BackgroundManager = new Class({
	
	element: null,
	marshal: null,

	currentBgImage: null,
	oldBgImage: null,

	spinner: null,
	
	initialize: function( aMarshal ){
		this.marshal = aMarshal;
		this.spinner = new Spinner( null, { message: "Hold up, loading..."} );
	},
	
	lowResImageLoaded: function(){
//		console.log( "\n\n:::::::lowResImageLoaded", this.toString(), "::::::::::::::::::::::\n\n " );		
		if( !this.marshal.isFirstRun ){	
			if( this.oldBgImage ) this.oldBgImage.slideOut();
			this.spinner.hide();
			this.currentBgImage.slideIn();		
		}else{
			this.currentBgImage.loadHighResImage();
		}
	
		this.marshal.isFirstRun = false;

	},
	
	loadPageBackground: function( lSrc, hSrc, dir ){
		
//		console.log( "loadPageBackground", lSrc, hSrc, this.marshal.dir );

		if( this.marshal.isFirstRun ){
			var position = { "left" : 0, "top": 0 };
		}else{
			var position = ( dir < 0 )? { "left": 0, "top": window.getSize().y } : { "left": 0, "top": -window.getSize().y };
		}
		
		if( this.currentBgImage ) this.oldBgImage = this.currentBgImage;
		this.currentBgImage = new mop.ui.BackgroundImage( lSrc, hSrc, this, { styles: position } );

	},
	
	loadProductBackground: function( lSrc, hSrc, dir ){
//		console.log( "loadProductBackground", lSrc, hSrc, this.marshal.transitionOrientation );
        this.dir = dir;
        var position = ( dir < 0 )? { "left": window.getSize().x, "top": 0 } : { "left": -window.getSize().x, "top": 0 };
        if( this.currentBgImage ) this.oldBgImage = this.currentBgImage;
        this.currentBgImage = new mop.ui.BackgroundImage( lSrc, hSrc, this, { styles: position } );

	},
	
	
	loadCollectionBackground: function( lSrc, hSrc, dir, orientation ){
//		console.log( "loadCollectionBackground", lSrc, hSrc, dir, orientation );
		this.dir = dir;
		var position = ( dir < 0 )? { "left": window.getSize().x, "top": 0 } : { "left": -window.getSize().x, "top": 0 };
		if( this.currentBgImage ) this.oldBgImage = this.currentBgImage;
		this.currentBgImage = new mop.ui.BackgroundImage( lSrc, hSrc, this, { styles: position } );
	},

	destroyImage: function( img ){
		if( img == this.oldBgImage ) this.oldBgImage = null;
		img.destroy();
		delete img;
		img = null;
	}
	
});

mop.ui.BackgroundImage = new Class({
	
	Implements: Options,
	
	marshal: null,
	lowResSrc: null,
	highResSrc: null,
	lowResImage: null,
	highResImage: null,
	inPosition: false,
	resizeEvent: null,

	initialize: function( lowResSrc, highResSrc, aMarshal, options  ){
		this.setOptions( options );
		this.marshal = aMarshal;
    	this.lowResSrc = lowResSrc;
    	this.highResSrc = highResSrc;
    	if ( this.lowResSrc ) {
    	    this.image = this.lowResImage = new Asset.image( lowResSrc, { 
    			styles: this.options.styles,
    			"class": "bgImage low",
    			alt: "Background image...",
    			onload: this.lowResImageLoaded.bind( this )
    		});
    	} else {
//    	    console.log( "no LowResSrc", options );
            this.marshal.currentBgImage = this;
            this.loadHighResImage( options );
    	}
        //		console.log( this.toString(), "initialize ", this.options, this.image.getStyles( "top", "left", "opacity", "zindex", "width", "height" ) );	
		this.resizeEvent = window.addEvent( "resize", this.resizeImage.bind( this ) );
	},
	
	toString: function(){
		return "[ object, mop.ui.BackgroundImage ]";
	},
		
	lowResImageLoaded: function(){
//		console.log( "lowResImageLoaded", this.toString(), this.highResSrc );
		$( document.body ).adopt( this.lowResImage );
		this.resizeImage();
		this.marshal.lowResImageLoaded( this );
	},
	
	loadHighResImage: function( options ){
		
		if( this.marshal.currentBgImage != this ) return;

		if( this.lowResImage ) this.inPosition = true;
		
		var w = window.getCoordinates();
        var pos = ( this.lowResImage )? this.lowResImage.getStyles(  "top", "left", "width", "height", "position" ) : options.styles;
//        console.log( "loadHighResImage", pos );

		this.highResImage = new Asset.image( this.highResSrc, { 
			styles: Object.extend( { "opacity": 0 }, pos ),
			"class": "bgImage high",
			alt: "Background Image",
			onload: this.replaceLowQualityImageWithHighQualityImage.bind( this )
		});
//		if( !this.lowResImage ) this.image = this.highResImage;
		this.resizeImage();
	},
	
	replaceLowQualityImageWithHighQualityImage: function(){
//		console.log( "replaceLowQualityImageWithHighQualityImage", this.toString(),  this.highResSrc, this.highResImage.getStyles( "top", "left", "width", "height", "zindex", "position" )  );
		if( this.marshal.currentBgImage != this ) return;
		$( document.body ).adopt( this.highResImage );
		if( this.lowResImage ){
    		this.highResImage.set( "morph", { duration: 1500, onComplete: this.onImageFadeInComplete.bind( this ) } );		    
    		this.image = this.highResImage;
		}else{
    		this.highResImage.set( "morph", { duration: 1500, onComplete: this.onImageFadeInComplete.bind( this ) } );
    		this.image = this.highResImage;
    		this.slideIn();		    
		}
		this.resizeImage();
		this.highResImage.morph( { 'opacity' : 1 } );
	},

	onImageFadeInComplete: function(){
//		console.log( "onImageFadeInComplete", this.toString(), this.highResSrc );
		if( this.marshal.currentBgImage != this ) return;
		this.image = this.highResImage;
		this.resizeImage();
		if( this.lowResImage ) this.lowResImage.destroy();		
	},

	resizeImage: function() {
		if( !this.image ) return;
		if( this.marshal.currentBgImage != this ) return;
		// calculate aspect ratio		
		var win = window.getSize();
		var w = win.x;
		var h = win.y;
		var winRatio = w / h;
		var imgSize = this.image.getSize();
		var imgRatio = imgSize.x / imgSize.y;
		if ( winRatio > imgRatio ) {
			// scale image to window based on width
			var newHeight = ( w / imgSize.x ) * imgSize.y;
			var newWidth = w;
		} else {
			// scale image to window based on height
			var newHeight = h;
			var newWidth = ( h / imgSize.y ) * imgSize.x;
		}
		// set styles based on calculated positions
		
		if( this.marshal.currentBgImage == this ){
			if( this.lowResImage ){
				this.lowResImage.setStyles({
					width: newWidth,
					height: newHeight
				}); 
			}
			if( this.highResImage ){
				this.highResImage.setStyles({
					width: newWidth,
					height: newHeight			
				});
			} 
		}
	},
	
	slideOut: function( dir ){

//		console.log( "slideOut", this.toString(), this.highResSrc, dir );

		var app = this.marshal.marshal;
		var win = window.getSize();
		var img = this.image.getSize();
		var dir = this.marshal.dir;
		var pos;
		if( app.transitionOrientation == "vertical" ){
			pos = ( dir > 0 )? { "left": 0 , "top": img.y } : { "left": 0 , "top": -img.y };
		}else{
			pos = ( dir > 0 )? { "left": win.x , "top": 0 } : { "left": -win.x , "top": 0 };			
		}

		this.image.set( "morph", { duration: 1000, onComplete: this.marshal.destroyImage.bind( this.marshal, this ) } );
		this.image.morph( pos );			

	},
	
	slideIn: function(){
//		console.log( "slideIn", this.image.getStyles( "top", "left" ), this.toString(), this.highResSrc );
//		if( this.marshal.currentBgImage != this ) return;
        var cb = ( this.lowResImage )? this.loadHighResImage.bind( this ) : function(){ this.inPosition = true };
		this.image.set( "morph", { duration: 1000, onComplete:cb } );
		this.image.morph( { "left": 0, "top": 0 } );
	},
	
	destroy: function(){
//		console.log( "destroy", this.toString(), this.highResSrc );
		window.removeEvent( "resize", this.resizeEvent );
		if( this.highResImage ) this.highResImage.destroy();
		if( this.lowResImage ) this.lowResImage.destroy();
		this.lowResSrc = this.highResSrc = this.image = this.lowResImage = this.highResImage = null;
		delete this.lowResSrc;
		delete this.highResSrc;
		delete this.lowResImage;
		delete this.highResImage;
		delete this.image;
	}




});

krsp.Collection = new Class({

	toString: function(){ return "[ object, krs.Collection ]"; },
	
	initialize: function( anElement, aMarshal ){
//		console.log( this.toString(), "initialized" );
		this.marshal = aMarshal;
		this.element = $( anElement );
//		this.marshal.setActiveNavItem( $( "collectionNavItem" ) );
		var collectionLinks = anElement.getElements( "li" );		
		anElement.setStyle( "overflow", "auto" );
		anElement.getElement( "ul" ).setStyle( "width", ( 95 + 24 ) *collectionLinks.length + 32 );
		collectionLinks.each( function( anLi, anIndex ){
			anLi.store( "index", anIndex );	
			anLi.addEvent( "click", this.thumbClicked.bindWithEvent( this, anLi ) );
		}, this );
		this.show();
	},

	thumbClicked: function( e, anLi ){
		mop.util.stopEvent( e );
		// if( this.activeThumb ) this.activeThumb.removeClass( "active" );
		anLi.addClass( "active" );
		var hSrc = anLi.getElement( "a" ).get( "href" );
		var lSrc = anLi.getElement( "a" ).get( "href" ).replace( "/hi/", "/low/" ).replace(".jpg",".png");
//		console.log( this.toString(), "thumbClicked", hSrc, lSrc );
		var dir = 1
		dir = ( this.activeThumb && anLi.retrieve( "index" ) > this.activeThumb.retrieve( "index" ) ) ? -1 : 1;
		this.activeThumb = anLi;
		this.marshal.backgroundManager.loadCollectionBackground( lSrc, hSrc, dir, "horizontal" );
	},
	
	hide: function( destructive ){
		this.element.dissolve( { onComplete: function(){
			if( destructive ) this.element.empty();
			this.visible = false;
		}.bind( this ) });
	},

	show: function(){
		this.element.reveal( { onComplete: function(){
			this.visible = true;
		}.bind( this ) });
	},

	destroy: function(){
		this.element.destroy();
		this.element = null;
	}
	
});

krsp.store.ProductThumbNav = new Class({
	
	element: null,
	marshal: null,
	listing: null,
	visible: false,
	
	initialize: function( anElement, aMarshal ){
//		console.log( this.toString(), "initialized" );
		this.marshal = aMarshal;
		this.build( anElement );
	},
	
	toString: function(){
		return "[ object, krsp.ProductThumbNav ]";
	},
	
	build: function( anElement ){
		this.element = anElement;
		$( document.body ).adopt( this.element );
		this.element.set( "reveal",  { duration: 3000 } );
		this.wireThumbs();
		this.show();
	},
	
	wireThumbs: function(){
		
		var thumbs = this.element.getElements( "li" );

		this.element.setStyle( "overflow", "auto" );
		this.element.getElement( "ul" ).setStyle( "width", ( 95 + 24 ) *thumbs.length + 32 );
		
		thumbs.each( function( aThumb, index ){
//			console.log( "wireThumbs>>>>> ", aThumb );
			aThumb.addEvent( "click", this.thumbClicked.bindWithEvent( this, aThumb ) );
		}, this );
	},

	thumbClicked: function( e, aThumb ){
		mop.util.stopEvent( e );
		this.marshal.backgroundManager.spinner.show();
		if( this.activeThumb ){
			this.activeThumb.removeClass( "active" );
			this.oldActiveThumb = this.activeThumb;
		}
		this.activeThumb = aThumb;
		this.activeThumb.addClass( "activate" );
		var href = aThumb.getElement( "a" ).get( "href" );
		var insertionPoint = href.indexOf( "store/" );
		var path = href.substr( insertionPoint, href.length );
		window.location.hash = "dl:" + path;
		var newHref = href.substr( 0, insertionPoint ) + "ajax/compound/" + path;
//		console.log( "{ oldHref: ", href, ", newHref: ", newHref, " }" );
		this.marshal.getProduct( newHref );
	},
	
	reload: function( someHTML ){
//		console.log( this.toString(), "reload", someHTML );
		if( this.visible ){
			this.element.dissolve( { onComplete: function(){
				this.element.empty();
				this.element.adopts( someHTML.getChildren() );
				this.wireThumbs();
				this.element.set( "reveal",  { duration: 300, onComplete: null } );
				this.show.delay( 30, this );
			 }.bind( this ) });			
		}else{
			this.element.empty();
			this.element.adopt( someHTML.getChildren() );
			this.wireThumbs();
			this.element.set( "reveal",  { duration: 300, onComplete: null } );
			this.element.reveal( this.element );			
		}
		this.visible = !this.visible;
	},

	hide: function( destructive ){
		this.element.dissolve( { onComplete: function(){
			if( destructive ) this.element.empty();
			this.visible = false;
		}.bind( this ) });
	},

	show: function(){
		this.element.reveal( { onComplete: function(){
			this.visible = true;
		}.bind( this ) });
	},

	destroy: function(){
		this.element.destroy();
		this.element = null;
	}
	
});

mop.util.Broadcaster = new Class({

	listeners: [],

	addListener: function( aListener ){
		this.listeners.push( aListener );
	},

	removeListener: function( aListener ){
		if( this.listeners.contains( aListener ) ) this.listeners.erase( aListener );
	},

	broadcastEvent: function( eventToFire ){
//		console.log( "broadcastEvent", eventToFire );
		this.listeners.each( function( aListener ){
//			console.log( "::::", aListener.toString(), eventToFire );
			aListener.fireEvent( eventToFire );
		});
	}

});

window.addEvent( "domready", function(){
	krsp.app = new krsp.App();
});

