/** 
 * Product detail page module
 * 
 * @module      ProductDetail
 * @author      Preet Jassi
 * @file        product.js 
 * @copyright   (c) 2011 Indochino Apparel Inc. 
 */
    
indo.Util.register('indo-productdetail', function(Y){

    /**
    * Product Detail page module
    * @module CollectionGallery
    */
    var ProductDetail = (function(){
        
        /**
        * The className -> callback event mapping
        * @property {object} eventMap
        */
        var eventMap = {};
        
        return {
            
            
            /**
            * DOM reference to materialInfo con
            * @property {Y.Node} materialInfo
            */
            
            /**
            * List of all material info descriptions
            * @property {Y.NodeList} descriptions
            */
            
            /**
            * DOM reference to the opacity wrap for descrips
            * @property {Y.Node} wrap
            */
            
            /**
            * DOM reference to the floating arrow
            * @property {Y.Node} arrow
            */
            
            /**
            * The previously selected description
            * @property {Y.Node} prev
            */
            
            
            /* -------------------------------------------------------  */
            /*                                                          */
            /*                  Core Methods                            */
            /*                                                          */
            /* -------------------------------------------------------- */
    
            /**
            * Initializes DOM references
            * @return {void}
            * @method init
            */
            init: function() {
        
                //get DOM references
                this.materialInfo = Y.one('#primary_product_info .material-information');
                
                //we are on the product page, set the height of the wrap element
                if (this.materialInfo) {
                    
                    this.descriptions = this.materialInfo.one('.material-info-description');
                    this.wrap = Y.one('#product-detail-screen');
                    this.arrow = Y.one('#material-info-arrow');

                    this.wrap.setStyle('height', this.materialInfo.get('offsetTop') + 'px');
                    this.materialInfo.delegate('hover', Y.bind(this.hoverIn, this), Y.bind(this.hoverOut, this), '.material-info-icon');
                }
            
                this.initEvents();
                    
            },
            
            /**
            * Sets the className to callback event mapping.
            * @return {void}
            * @method initEvents
            */
            initEvents: function() {

                eventMap = {
                    'gallery-trigger': this.openGallery,
                    'add-to-waitlist': this.addToWaitlist,
                    'free-shipping-label': this.showShippingInfo
                };
                
                //track the add to bag event
                if ( Y.one('.product-add-to-bag-form') ){
                    Y.one('.product-add-to-bag-form').on('submit', this.addToBag, this);
                }

            },
            
            /**
            * Didn't yo momma teach you to clean up after yoself?
            * @return {void}
            * @method destruct
            */
            destruct: function() {                    
                
                //detach events
                if (this.materialInfo) {
                    this.materialInfo.detach();
                }
                
                //remove dom references
                this.materialInfo =
                this.descriptions =
                this.wrap =
                this.arrow = 
                this.prev = null;
                
            },
            
            /**
            * Single click handler
            * @param {Y.Event} e
            * @return {void}
            * @method onviewevent
            */
            onviewevent: function(e) {
              
                var targ = e.target,
                    classes = targ.get('className').split(' '),
                    length = classes.length;

                //determine callback function dependant upon the classname of the target
                while (length--) {
                    if (eventMap[classes[length]]) {
                        eventMap[classes[length]].call(this, e);
                        e.preventDefault();
                        return false;
                    }
                }
                                  
            },
            
            /* -------------------------------------------------------  */
            /*                                                          */
            /*                  Event Handlers                          */
            /*                                                          */
            /* -------------------------------------------------------- */
            
            
            /**
            * Open the Image Gallery
            * @param {Y.Event}
            * @param {void}
            * @method openGallery
            */
            openGallery: function(e) {

                var targ = e.target,
                    imgs = e.target.ancestor('ul').all('img'),
                    count = 0;

                imgs.each(function(img, index){
                    if (img === targ) count = index;
                });

                Y.fire('gallery:open',{
                    'images': indo.Util.getContextData('galleryImages'),
                    'imgIndex': count
                });

            },
            
            /**
            * Log that the user has added the item to the bag
            * @param {Y.Event}
            * @method addToBag
            */
            addToBag: function(e) {

                indo.Util.record('Added to Bag', {
                    'source': 'productpage'
                });
                
            },

            /**
            * Adds the product to the waitlist
            * @param {Y.Event}
            * @return {void}
            * @method addToWaitlist
            */
            addToWaitlist: function(e) {

                var targ = e.target;

                if ( !(targ.getAttribute('href').indexOf('?sign-in') + 1) ) {

                    if (!targ.hasClass('btn-disabled')) {

                        targ.addClass('btn-disabled' );
                        targ.setContent('Adding to waitlist...');

                        var boom = e.target.getAttribute('href').split('/'), //heashot
                            product_id = boom[boom.length-1];

                        Y.fire('shopping-bag:add-product-to-waitlist',{
                            'product_id': product_id,
                            'targ': targ
                        });

                    }

                } else {
                    window.location.replace( targ.getAttribute('href') );
                }

            },
            
            
            /**
            * displays the tooltips on hover
            * @return {void}
            * @param {Event} e
            * @method hoverIn
            */
            hoverIn: function(e) {

                var targ = e.target,
                    targ = (targ.get('nodeName').toLowerCase() === 'img') ? targ.ancestor('.material-info-icon') : targ,
                    next = targ.next('.material-info-description');
                
                if (!this.prev) {

                    this.wrap.setStyle('opacity', '0');
                    this.wrap.setStyle('display', 'block');
                    this.wrap.transition({
                        opacity:0.8,
                        duration:0.5
                    });
                    
                    next.setStyle('height', '0px');
                    next.setStyle('display', 'block');
                    next.transition({
                        height: '104px',
                        duration: 0.5
                    });
                    
                } else {

                    this.wrap.setStyle('display', 'block');
                    next.setStyle('display', 'block');

                }

                this.arrow.setStyle('display', 'block');
                this.arrow.transition({
                    left: ((targ.get('offsetWidth')/2) + targ.get('offsetLeft') - 10) + 'px',
                    duration: 0.5
                });

                this.prev = next;        

            },

            /**
            * hides the tooltips when we hover out
            * @return {void}
            * @method hoverOut
            */
            hoverOut: function() {

                this.arrow.setStyle('display', 'none')
                this.prev.setStyle('display', 'none');          
                this.wrap.setStyle('display', 'none');

            },
            
            /**
            * Show the shipping info
            * @param {Y.Event}
            * @return {void}
            * @method showShippingInfo
            */
            showShippingInfo: function(e) {
                
                indo.Util.showDialog( indo.Util.getContextString('shipping'), false );
                indo.Util.resizeDialog( '660px' );
                
            },
            
            /* -------------------------------------------------------  */
            /*                                                          */
            /*          Custom Event Handlers / XHR Callbacks           */
            /*                                                          */
            /* -------------------------------------------------------- */
            
            /**
            * Callback for custom event when the product is added to the wait list
            * @param {object} custom event callback object (contains XMLHttpRequest and arguments)
            * @return {void}
            * @method addedToWaitlist
            */
            addedToWaitlist: function(obj) {
                obj.args.targ.setContent('Added to waitlist');
            }
            
            
        };
        
    }());
    
    //constructor
    Y.on('util:init', ProductDetail.init, ProductDetail);
    Y.on('util:destruct', ProductDetail.destruct, ProductDetail);
    Y.on('util:onviewevent', ProductDetail.onviewevent, ProductDetail);
    
    //shopping bag events
    Y.on('shopping-bag:product-added-to-waitlist', ProductDetail.addedToWaitlist, ProductDetail);
    
}, '0.0.1,', {requires:['transition', 'json', 'event-hover', 'indo-gallery']});


