YUI({combine: true, timeout: 10000}).use("overlay", "io", "json", "plugin", function(Y) {

    /* Standard Module IO Plugin Constructor */
    function StdModIOPlugin(config) {
        StdModIOPlugin.superclass.constructor.apply(this, arguments);
    }

    /* 
     * The namespace for the plugin. This will be the property on the widget, which will 
     * reference the plugin instance, when it's plugged in
     */
    StdModIOPlugin.NS = "io";

    /*
     * The NAME of the StdModIOPlugin class. Used to prefix events generated
     * by the plugin class.
     */
    StdModIOPlugin.NAME = "stdModIOPlugin";

    /*
     * The default set of attributes for the StdModIOPlugin class.
     */
    StdModIOPlugin.ATTRS = {

        /*
         * The uri to use for the io request
         */
        uri : {
            value:null
        },

        /*
         * The io configuration object, to pass to io when intiating a transaction
         */
        cfg : {
            timeout : 3000,
            method:"GET",
            headers: { 'X_REQUESTED_WITH': 'XMLHttpRequest'}
        },

        /*
         * The default formatter to use when formatting response data. The default
         * implementation simply passes back the response data passed in. 
         */
        formatter : {
            valueFn: function() {
                return this._defFormatter;
            }
        },

        /*
         * The Standard Module section to which the io plugin instance is bound.
         * Response data will be used to populate this section, after passing through
         * the configured formatter.
         */
        section: {
            value:Y.WidgetStdMod.BODY,
            validator: function(val) {
                return (!val || val == Y.WidgetStdMod.BODY || val == Y.WidgetStdMod.HEADER || val == Y.WidgetStdMod.FOOTER);
            }
        },

        /*
         * The default loading indicator to use, when an io transaction is in progress.
         */
        loading: {
            value: '<img class="yui-loading" width="32px" height="32px" src="/img/ajax-loader.gif">'
        }
    };

    /* Extend the base plugin class */
    Y.extend(StdModIOPlugin, Y.Plugin.Base, {

        /*
         * Initialization code. Called when the 
         * plugin is instantiated (whenever it's 
         * plugged into the host)
         */
        initializer: function(config) {
        },

        /*
         * Destruction code. 
         */
        destructor : function() {
        },

        /*
         * IO Plugin specific method, use to initiate a new io request using the current
         * io configuration settings.
         */
        dispatch : function() {
            section = this.get("section");
         
            if (section && !this._activeIO) {
                var uri = this.get("uri");
         
                if (uri) {
         
                    cfg = this.get("cfg") || {};
                    cfg.on = cfg.on || {};
         
                    cfg.on.start = cfg.on.start || Y.bind(this._defStartHandler, this);
                    cfg.on.complete = cfg.on.complete || Y.bind(this._defCompleteHandler, this);
         
                    cfg.on.success = cfg.on.success || Y.bind(this._defSuccessHandler, this);
                    cfg.on.failure = cfg.on.failure || Y.bind(this._defFailureHandler, this);
         
                    cfg.method = cfg.method; // io defaults to "GET" if not defined
         
                    Y.io(uri, cfg);
                }
            }
        },

        /*
         * The default io transaction success handler
         */
        _defSuccessHandler : function(id, o) {
            var response = o.responseText;
            var section = this.get("section");
            var formatter = this.get("formatter");

            this.get("host").setStdModContent(section, formatter(response));
        },

        /*
         * The default io transaction failure handler
         */
        _defFailureHandler : function(id, o) {
            this.get("host").setStdModContent(this.get("section"), "Well this is embarrassing. Our system is having some trouble.  Please try again shortly.");
        },

        /*
         * The default io transaction start handler
         */
        _defStartHandler : function(id, o) {
            this._activeIO = o;
            this.get("host").setStdModContent(this.get("section"), this.get("loading"));
        },

        /*
         * The default io transaction complete handler
         */
        _defCompleteHandler : function(id, o) {
            this._activeIO = null;        
        },

        /*
         * The default response formatter
         */
        _defFormatter : function(val) {
            return val
        }
    });

    // The default formatter, responsible for converting the JSON responses recieved,
    // into HTML, using JSON for the parsing step, and substitute for some basic templating functionality
    function AddToCartFormatter(val) {
        var formatted = "Error parsing feed data";
        try {
            var json = Y.JSON.parse(val);
            if (json) {
                var html = '<p class="add-to-cart-success">' + json.message + '</p>';
                html += '<p class="add-to-cart-product">' + json.product + '</p>';
                html += '<a href="/cart"><img src="/img/btn_checkout.png" alt="checkout button" style="margin-right: 10px;"/></a>';
                html += '<img src="/img/btn_continue_shopping.png" alt="continue shopping button" id="hide"/>';
                formatted = html;

            } else {
                formatted = "No Data Available";
            }
        } catch(e) {
            formatted = "Error parsing feed data";
        }
        return formatted;
    }

    // After DOM has been updated with the new html
    // run add an event
    function DOMupdated() {
        var hide = Y.one('#hide');
        if ( hide != undefined) {
            hide.on("click", function(e) {
                overlay.hide();
            });    
        }
    }    

    /* Create a new Overlay instance, with content generated from script */
    var overlay = new Y.Overlay({
        width:"300px",
        height:"150px",
        centered: true,
        zIndex:10
    });


 
    
    /**
     * ADD TO CART BUTTON
     */
     
    var button = Y.one('#add-to-cart');
    if(button != undefined) {
        button.on('click', function (e) {  
             e.preventDefault();
             // Add the Standard Module IO Plugin
            overlay.plug(StdModIOPlugin, {
            formatter: AddToCartFormatter,
                cfg:{
                    on: {
                        end: DOMupdated    
                    }
                }
            }); 
             
             // rendering the overlay here bc it takes into account any scrolling that might have occurred.
             overlay.render();
             overlay.show(); // in case it is clicked after overlay.hide runs
             overlay.io.set("uri", this.get('href') + "/format/json");
             overlay.io.dispatch();
        });
    }

     /**
     * Basic formatter for the cart view page
     */
     
    function ViewCartFormatter(val) {
        var json = Y.JSON.parse(val);
        var html = '<p class="view-cart-ajax">' + json.message + '</p>';
        return html;
    }      

    /* small overlay */
    var smallOverlay = new Y.Overlay({
        //width:"300px",
        //height:"150px",
        zIndex:10
    });
    

    
    /**
     * UPDATE QUANTITY
     */      
    var updateSubmitButton = Y.one('#update');
    if(updateSubmitButton != undefined) 
    {       
        updateSubmitButton.on('click', function (e) {  
            e.preventDefault();
            var processInputs = Y.all('.process');
            var params = "";
            
            // I added the class .process to each input that has a quantity
            // I wanted to just loop thru all of the input elements, but 
            // the submit button is an input element and that would 
            // add an extra if () clause to my for loop bc I would have to 
            // check to make sure that the input did not have type =="submit"
            
            Y.each(processInputs, function(v, k) {
                params += '&' + v.get('id') + '=';
                params += parseInt(v.get('value'));
            })            
            //remove the first "&" ... its kind of a hack
            var params = params.replace("&", '');

            
            // result
            // &73=2&74=4
            var href = e.currentTarget.get('href');
            var sUrl = href + 'products/' + params;
            window.location = sUrl;            

             
        })
    }

    
    
    
     

});
