﻿/*................. debug .................*/
function debug() {
    try{
        if (console && console.log) {            
            console.log.apply(console, arguments);            
        }
    }
    catch(e) {}
}

var M = {
    getEl : function(id)
    {
        return document.getElementById(id);
    },
    getUri : function()
    {
        return window.location.href.split('?')[0].split('#')[0]; 
    },
    /*................. toggleGrid .................*/
    toggleGrid : function() {    
        var $body = jQuery("body");    
        if ($body.hasClass("grid")) {
            $body.removeClass("grid");
        } else {
            $body.addClass("grid");
        }
    },
    getQueryString : function(val)
    {
        if (val==null) val = window.location.href;
        var q = val.split('?');
        if (q.length == 2)
        {
            q = q[1];
        }
        else
        {
            q = '';
        }
        
        return q;
    },
    getQueryStringParameter: function (paramName, url) {
        var m, q, i;

        url = url || window.location.href;

        i = url.indexOf('?');
        q = i >= 0 ? url.substr(i + 1) : url;

        // Remove the hash if any
        i = q.lastIndexOf('#');
        q = i >= 0 ? q.substr(0, i) : q;
        
        var REGEXP = /([^=&]+)=([^&]*)/g;
        REGEXP.lastIndex = 0;
        while ((m = REGEXP.exec(q))) {
            if (m[1] === paramName) {
                return decodeURIComponent(m[2]);
            }
        }

        return null;
    },
    formatCurrency : function(val)
    {
        var amount = parseFloat(val).toFixed(2);        
        var delimiter = ","; // replace comma if desired
        var a = amount.split('.',2)
        var d = a[1];
        var i = parseInt(a[0]);
        if(isNaN(i)) { return ''; }
        var minus = '';
        if(i < 0) { minus = '-'; }
        i = Math.abs(i);
        var n = new String(i);
        var a = [];
        while(n.length > 3)
        {
	        var nn = n.substr(n.length-3);
	        a.unshift(nn);
	        n = n.substr(0,n.length-3);
        }
        if(n.length > 0) { a.unshift(n); }
        n = a.join(delimiter);
        if(d.length < 1) { amount = n; }
        else { amount = n + '.' + d; }
        amount = minus + amount;
        return '$' + amount;
    },
    parseFloat : function(val)
    {
        //alert(val + ':' +  val.replace(/[^0-9.]/g, ''));
        //val = val.replace(/[^0-9.]/g, '');
        
        return parseFloat(val);
    },
    parseInt : function(val)
    {
        //val = val.replace(/[^0-9.]/g, '');
        return parseInt(val);
    },
    getKeyCode : function(e){
        var keyCode = null;
        if (window.event)
        {
            keyCode = e.keyCode;
        } 
        else if (e.which)
        {
            keyCode = e.which;
        }
        return keyCode
    },
    keyTest : function(e, exp)
    {
        var keyCode = MUtil.getKeyCode;        
        
        if (keyCode==null || keyCode==8 || keyCode == 16){
            return true;
        }
        var keyChar = String.fromCharCode(keyCode);         
        return exp.test(keyChar);    
    },
    focusAndSelect : function(textInput)
    {
        textInput.focus();
        if (textInput.createTextRange)
        {
            var oRange = textInput.createTextRange();
            oRange.moveStart("character", 0);
            oRange.moveEnd("character", textInput.value.length);
            oRange.select();

        } else if (textInput.setSelectionRange)
        {
            textInput.setSelectionRange(0, textInput.value.length);
        }
    },
    urldecode : function(str) 
    {
        if (decodeURIComponent)
        {
            str = decodeURIComponent(str);
        } 
        else
        {
            str = unescape(str);
        }
        str = str.replace(/\+/g, ' ');        
        return str;
    },
    urlencode : function(str)
    {
        if (encodeURIComponent) 
        {
            str = encodeURIComponent(str);
        } 
        else
        { 
            str = escape(str).replace(/\+/g,'%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
        }
        return str;
    },
    getMouseCoords : function(e)
    {
        var posx = 0;
	    var posy = 0;
	    if (!e) var e = window.event;
	    if (e.pageX || e.pageY) 	{
		    posx = e.pageX;
		    posy = e.pageY;
	    }
	    else if (e.clientX || e.clientY) 	{
		    posx = e.clientX + document.body.scrollLeft
			    + document.documentElement.scrollLeft;
		    posy = e.clientY + document.body.scrollTop
			    + document.documentElement.scrollTop;
	    }
	    return {x:posx,y:posy};
    },
    getTarget : function(e)
    {
        return (e.srcElement) ? e.srcElement : e.currentTarget;
    }
};

M.Keys = {
    EVENTURL_KEY : "_e_",
    EVENTID_KEY : "_e_id_",
    DIMENSION_KEY : "_dim_",
    CARTSIZEID_KEY : "_cs_id_",
    IMAGEID_KEY : "_i_id_",
    CUSTOMPRODUCT_KEY : "_cp_id_",
    CARTCUSTOMPRODUCT_KEY : "_ccp_id_"
};

M.ImageUtil =
{
    getEventUrl: function (eventUrl) {
        return Paths.eventUrlPath.replace(M.Keys.EVENTURL_KEY, eventUrl);
    },
    getImageUrl: function (eventID, imageID, doBW, dimension) {
        var urlPath = Paths.imageUrlPath;

        return urlPath.replace(M.Keys.EVENTID_KEY, eventID)
            .replace(M.Keys.IMAGEID_KEY, imageID)
            .replace(M.Keys.DIMENSION_KEY, dimension) +
            M.ImageUtil.getImgStyleQS(doBW);
    },
    getCartSizePreviewUrl: function (eventID, cartSizeID, dimension) {
        var urlPath = Paths.cartSizePreviewUrlPath;

        urlPath = urlPath
            .replace(M.Keys.EVENTID_KEY, eventID)
            .replace(M.Keys.CARTSIZEID_KEY, cartSizeID)
            .replace(M.Keys.DIMENSION_KEY, dimension);

        return urlPath;
    },
    getCustomProductImageUrl: function (customProductID, dimension) {
        var urlPath = Paths.customProductImageUrlPath;

        return urlPath.replace(M.Keys.CUSTOMPRODUCT_KEY, customProductID)
            .replace(M.Keys.DIMENSION_KEY, dimension);
    },
    getImgStyleQS: function (doBW) {
        var styleString = "?bw=";
        if (doBW) {
            return styleString + "1";
        }
        return "";
    },
    getDimensionString: function (d) {
        var width = d.width || d.Width;
        var height = d.height || d.Height;
        return width + "x" + height;
    },
    getDimensionFromString: function (str) {
        var split = str.split('x');
        return new Dimension(parseInt(split[0]), parseInt(split[1]));
    },
    getCropCoordsString: function (coords) {
        return coords.XCenter + " " + coords.YCenter + " " + coords.Width + " " + coords.Height;
    },
    getCropCoordsFromString: function (str) {
        var split = str.split(' ');

        var c = new CropCoords();
        c.XCenter = parseFloat(split[0]);
        c.YCenter = parseFloat(split[1]);
        c.Width = parseFloat(split[2]);
        c.Height = parseFloat(split[3]);
        return c;
    },
    determineCropCoords: function (imageWidth, imageHeight, cropLeft, cropTop, cropWidth, cropHeight) {
        var c = new CropCoords();

        c.Width = cropWidth / imageWidth;
        c.Height = cropHeight / imageHeight;
        c.XCenter = (cropLeft + (cropWidth / 2)) / imageWidth;
        c.YCenter = (cropTop + (cropHeight / 2)) / imageHeight;

        return c;
    },
    getOrientation: function (w, h) {
        if (w > h) return "H";
        if (h > w) return "V";
        if (w == h) return "S";
    },
    getRatio: function (w, h) {
        return w / h;
    },
    getOrientationRatio: function (w, h) {
        if (w >= h) return w / h;
        else return h / w;
    },
    getWidthFromRatio: function (height, ratio) {
        return parseInt(Math.floor(height * ratio));
    },
    getHeightFromRatio: function (width, ratio) {
        return parseInt(Math.floor(width / ratio));
    },
    getShortSizeFromRatio: function (longSize, ratio) {
        if (ratio <= 1) return M.ImageUtil.getWidthFromRatio(longSize, ratio);
        else return M.ImageUtil.getHeightFromRatio(longSize, ratio);
    },
    getLongSizeFromRatio: function (shortSize, ratio) {
        if (ratio <= 1) return M.ImageUtil.getHeightFromRatio(shortSize, ratio);
        else return M.ImageUtil.getWidthFromRatio(shortSize, ratio);
    },
    getDimensionForMaxSize: function (maxWidth, maxHeight, imageWidth, imageHeight) {

        var ratio = imageWidth / imageHeight;

        var innerRatio = imageWidth / imageHeight;
        var outerRatio = maxWidth / maxHeight;

        if (outerRatio > innerRatio)
        {
            //Width is wider - so bound by height.
            return new Dimension(parseInt(innerRatio * maxHeight), (maxHeight));
        }
        else
        {
            //Height is higher, or aspect ratios are identical.
            return new Dimension(maxWidth, parseInt(maxWidth / innerRatio));
        }
    }
}

M.BuyableItemUtil = {
    getActionButtonSubtract : function()
    {
        return M.HtmlUtil.getActionButtonATag('action-button-subtract', '', 'Subtract 1 from the quantity', null, true);
    },
    getActionButtonAdd : function()
    {
        return M.HtmlUtil.getActionButtonATag('action-button-add', '', 'Add 1 to the quantity', null, true);
    },
    getQuantityInput : function(bi)
    {
        var inputHtml = "<div class=\"action-buttons action-buttons-quantity\">" +
                        M.BuyableItemUtil.getActionButtonSubtract() +                        
                        "<input type=\"text\" name=\"{0}\" meta='{2}' class=\"pls-qty action-button-input text\" maxlength=\"3\" value=\"{1}\" alt=\"{1}\"  />" + 
                        M.BuyableItemUtil.getActionButtonAdd() +
                        "</div>";
        
        var qtyDisplay = (bi.qty > 0) ? bi.qty : '';
        
        var meta = '{"qty_req":' + (bi.qty_req || 1) + '}';

        return String.format(inputHtml,
            bi.f_key,
            qtyDisplay,
            meta);
    }
}

M.HtmlUtil = {
    buttonWarningClass : "button-warning",
    buttonOkClass : "button-ok",
    getActionButtonATag : function(className, text, title, id, is3D, isSelected, attributes)
    {
        var format = Paths.actionButtonATagFormat;
        
        var attr = '';
        var attrform = ' {0}="{1}"';
        if (title!=null && title.length > 0) attr += String.format(attrform, 'title', title);
        if (id!=null && id.length > 0) attr += String.format(attrform, 'id', id);  
        var spanClass = (is3D) ? ' class="button"' : '';
        var selectedClass = (isSelected) ? " class=\"selected\"" : "";

        
        if (attributes!=null)
        {
            var attrs = '';
            for (var attrKey in attributes)
            {
                attrs += String.format('{0}="{1}"', attrKey, attributes[attrKey]);
            }
            attr += ' ' + attrs;
        }
        
        return String.format(format, className, text, attr, spanClass, selectedClass);
    },
    getActionButtonTag : function(className, label, isDefault)
    {
        var format = Paths.actionButtonTagFormat;
        
        var cls = className + ((isDefault) ? ' default' : '');
        
        return String.format(format, cls, label);
    },
    setActionLoading : function($actionButtons, doRemove)
    {
        var actionLoadingClass = "action-buttons-loading";
        
        if (!doRemove) $actionButtons.addClass(actionLoadingClass);
        else $actionButtons.removeClass(actionLoadingClass);
    },
    setActionButtonWarning : function($actionButton, doRemove)
    {
        M.HtmlUtil.setClass($actionButton, M.HtmlUtil.buttonWarningClass, doRemove);                
    },
    setActionButtonOk : function($actionButton, doRemove)
    {
        M.HtmlUtil.setClass($actionButton, M.HtmlUtil.buttonOkClass, doRemove);                
    },
    setActionButtonLabel : function($actionButton, label)
    {
        $actionButton.find("strong").html(label);
    },
    setClass : function($el, className, doRemove)
    {
        if (!doRemove)$el.addClass(className);
        else $el.removeClass(className);
    },
    setActionButtonSelected : function($actionButton, isSelected)
    {
        var $div = $actionButton.find('div').eq(0);
        M.HtmlUtil.setClass($div, 'selected', !isSelected);
    },
    toggleActionButton : function($actionButton)
    {
        $actionButton.parent().find('a').each(function(){
            M.HtmlUtil.setActionButtonSelected($(this), false);
        });
        
        M.HtmlUtil.setActionButtonSelected($actionButton, true);
    },
    wrapImgShadow : function($img, imageWidth, imageHeight, cssClass)
    {
        $img = $($img);
        
        $img.addClass('img').css ({ 
            width: imageWidth + 'px',
            height: imageHeight + 'px'
        });
        
        var $imgWrap = $(document.createElement('div'));
        
        $imgWrap.html($img);
        
        var imgHtml = $imgWrap.html();
        
        $imgWrap = null;
        
        var shadowHtml = '<div class="img-shadow {3}"> \
                            <div class="img-shadow-w"> \
                            <div class="tl shd" style="width:{0}px;height:{1}px;"></div> \
                            {2} \
                            <div class="br shd" style="width:{0}px;height:{1}px;"></div> \
                            <div class="bl shd"></div> \
                            <div class="tr shd"></div> \
                            </div> \
                          </div>';
        
        
        return String.format(shadowHtml, imageWidth, imageHeight, imgHtml, cssClass);
    }
}

M.AjaxUtil = {
    handler : '/ajaxhandler',
    checkouthandler : '/checkouthandler',
    sendPostRequest : function(formObj, callback, url)
    {
        url = url || M.AjaxUtil.handler;
        
        // . look for site provider settings
        var $pid = $("#" + Paths.proIDKey);
        if ($pid.length > 0)
        {
            formObj[Paths.proIDKey] = $pid.val();
            formObj[Paths.customerKey] = $("#" + Paths.customerKey).val();
        }
        
        YUI().use('json-parse', function(Y)
        {
            $.post( 
                url, 
                formObj, 
                function(data)
                {
                    callback(Y.JSON.parse(data));
                },
                'text'
           );
       });
    },
    getCartCount : function(callback)
    {
        M.AjaxUtil.sendPostRequest( 
            { action: 'getCartCount' }, 
            callback );  
    },
    updateUserCartCount : function(count)
    {
        $span = $("#user-counts-cartcount");
        if (arguments.length > 0)
        {
            $span.html(count);
        }
        else
        {
            M.AjaxUtil.getCartCount(function(data)
            {
                $span.html(data.count);
            });            
        }
    },
    getCartItems : function(callback)
    {
        M.AjaxUtil.sendPostRequest(
            { action : 'getCartItems' },
            callback
        );       
    },
    getCartItem : function(cartSizeID, cartCustomProductID, callback)
    {
        cartSizeID = cartSizeID || '';
        cartCustomProductID = cartCustomProductID || '';
        
        M.AjaxUtil.sendPostRequest(
            { 'action' : 'getCartItem',
              'cs_id' : cartSizeID,
              'ccp_id' : cartCustomProductID
            }, callback );        
    },
    handleCartItemQty : function(f_key, qty, callback)
    {
        M.AjaxUtil.sendPostRequest(            
            { 'action' : 'setCartItemQty',
              'f_key' : f_key,
              'qty' : qty
            },
            callback
        );
    },
    handleBuyPhotoItemQty : function(key, qty, callback)
    {
        var formObj = { 'format' : 'json' };
        formObj[key] = qty;
        
        M.AjaxUtil.sendPostRequest(
            formObj,
            callback,
            M.getUri()
        );
    },
    updateCartSizeCrop : function(cartSizeId, cropCoords, callback)
    {
        M.AjaxUtil.sendPostRequest(            
            { 
              'action' : 'setCartSizeCrop',
              'cs_id' : cartSizeId,
              'crop' : cropCoords.toString()
            },
            callback
        );
    },
    setImageService : function(cartId, serviceName, enabled, callback)
    {
        M.AjaxUtil.sendPostRequest(
            {
                'action' : 'setImageService',
                'c_id' : cartId,
                'service' : serviceName, 
                'enabled' : enabled
            },
            callback
        );
    },
    getCartTotals : function(callback)
    {
        M.AjaxUtil.sendPostRequest(
            {
            'action' : 'getCartTotals'
            },
            callback);
    },
    applyCouponCode : function(code, callback)
    {
        if (code==null || code.length == 0) 
        {
            callback(M.AjaxUtil.getFailure('Please enter a coupon code'));
        
            return;
        }
        
        M.AjaxUtil.sendPostRequest(
            { 
            'action' : 'applyCouponCode',
            'code' : code 
            },
            callback);
    },
    getCitiesForZip : function(zipCode, callback)
    {
         if (zipCode == null || zipCode.length == 0) { 
            
            callback(M.AjaxUtil.getFailure('Please enter a zip code'));
            
            return;
         }
         
         M.AjaxUtil.sendPostRequest(
            {
                'action' : 'getCitiesForZip',
                'zipCode' : zipCode
            },
            callback,
            M.AjaxUtil.checkouthandler          
         );
    },
    getCheckoutTotals : function(shipMethod, hasPhotoTicket, shipToPro, shippingCity, shippingCityID, shippingState, shippingZipCode, callback)
    {
        M.AjaxUtil.sendPostRequest(
            {
                'action' : 'getCheckoutTotals',
                'shipMethod' : shipMethod,
                'hasPhotoTicket' : hasPhotoTicket,
                'shipToPro' : shipToPro,
                'shippingCity' : shippingCity,
                'shippingCityID' : shippingCityID,
                'shippingState' : shippingState,
                'shippingZipCode' : shippingZipCode
            },
            callback,
            M.AjaxUtil.checkouthandler
        );
    },
    getFailure : function(reason)
    {
        return { 'success' : false, 'reason' : reason };
    }
}

function Dimension(_width, _height)
{
    var obj = {
        Width: _width,
        Height: _height,
        toString : function () {
            return M.ImageUtil.getDimensionString(obj);
        },
        flip : function()
        {
            return new Dimension(_height, _width);
        },
        getOrientation : function()
        {
            return M.ImageUtil.getOrientation(_width, _height);
        },
        getRatio : function()
        {
            return M.ImageUtil.getRatio(_width, _height);
        },
        matchOrientation : function(width, height)
        {
            if (obj.getOrientation() != M.ImageUtil.getOrientation(width, height))
            {
                return obj.flip();
            }          
              
            return obj;            
        }
    };
    
    return obj;
}

function CropCoords(x, y, w, h)
{
    x = x || 0.5;
    y = y || 0.5;
    w = w || 1;
    h = h || 1;
    
    var obj = {
        XCenter : x,
        YCenter : y,
        Width : w,
        Height : h,
        toString : function()
        {
            return M.ImageUtil.getCropCoordsString(obj);
        }
    };
    
    return obj;    
}




function init() {
    jQuery(document).keypress(function(e) {
        if (e.which == 103 && e.ctrlKey && e.altKey) // g 
        {
            M.toggleGrid();
            debug(e.which);            
        }
    });
}

jQuery(function() {
    init();
});

/*jQuery.fn.bind = function (bind) {
     return function () {
          console.count("jQuery bind count");
          console.log("jQuery bind %o", this);
          return bind.apply(this, arguments);
      };
}(jQuery.fn.bind);*/

// String Functions
String.format = function() {
  var s = arguments[0];
  for (var i = 0; i < arguments.length - 1; i++) {       
    var reg = new RegExp("\\{" + i + "\\}", "gm");             
    s = s.replace(reg, arguments[i + 1]);
  }

  return s;
}


var EventListener = {
    listeners : [],
    addListener : function(type, object, callback) {
        EventListener.listeners.push(new EventListenerVO(type, object, callback));
    },
    dispatchEvent : function(type, args) {
        for (var i=0;i<EventListener.listeners.length;i++)
        {
            var vo = EventListener.listeners[i];
            if (vo.type == type)
            {
                vo.callback.apply(vo.object, args)
            }
        }
    }
};

function EventListenerVO (type, object, callback) {
   this.object = object;
   this.callback = callback;
   this.type = type;   
}

