/**
* @fileOverview EveryDaySource.com JavaScript Library
* @author vizle.li
* @version 1.0
* @requires jQuery
* @update 2010-06-30
*/
/*!-- jQuery extend --*/
(function ($) {
    //init ajax global setting
    $.ajaxSetup({
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            var msg = textStatus;
            if (XMLHttpRequest) {
                msg = XMLHttpRequest.status + ': ' + XMLHttpRequest.statusText + '<br/><br/>You can retry later.';
            }
            //$.dialog(msg, 'warn');
        }
    });
    $.extend({
        /** 获取函数的事件event
        * @param e Function or Event
        * @returns {Event}
        */
        getEvent: function (e) {
            e = e || $.getEvent;
            var ev = window.event || e;  //ie,opera,webkit
            var KeyEvent;

            if (typeof (e) === 'function' && window.event === undefined) {//firefox
                KeyEvent = typeof (KeyEvent) === 'undefined' ? KeyboardEvent : KeyEvent;
                while (e && e.caller) {
                    e = e.caller || e;
                }
                ev = e.arguments && e.arguments[0];
                var cs = ev.constructor;
                ev = (cs === MouseEvent || cs === KeyEvent) ? ev : undefined;
            }
            return ev;
        },
        /** 获取触发事件的元素
        * @param e Event
        * @returns {Object} Element
        */
        getEventTarget: function (e) {
            var ev = $.getEvent(e);
            var obj = (!ev || typeof (ev) !== 'object') ? undefined : (ev.originalTarget || ev.srcElement);
            return obj;
        },
        /** 生成 唯一GUID
        * @param {Boolen} change
        * @return {String} guid
        */
        createGUID: function (cookieName, change) {
            // http://www.ietf.org/rfc/rfc4122.txt
            var s = [],
			hexDigits = "0123456789ABCDEF",
			guid = $.cookie(cookieName);
            if (!guid || change) {
                for (var i = 0; i < 32; i++) {
                    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
                }
                s[12] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
                s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01

                guid = s.join("");
                $.cookie(cookieName, guid, { expires: 0 });
            }
            return guid;
        },
        doChunk: function (items, process, context, callback) {
            var todo = items.concat(), delay = 25;
            var ss = +new Date();

            setTimeout(function () {
                var start = +new Date();

                do {
                    process.call(context, todo.shift(), todo);
                } while (todo.length > 0 && (+new Date() - start < 50));

                if (todo.length > 0) {
                    setTimeout(arguments.callee, delay);
                } else if (callback) {
                    callback(items);
                }

            }, delay);
        },
        /** 选项卡 */
        catTab: {
            open: function (tarTabID, tab) {
                var tarTab = $('#' + tarTabID),
					links = tarTab.find('a'),
					currTab = $(tarTab.get(0).CATTAB_SELECT);
                for (var i = 0, l = links.length; i < l; ++i) {
                    var tar = $(links[i]).attr('href').split('#')[1];
                    if (links[i] == currTab.get(0)) {
                        $(links[i]).removeClass('select');
                        $('#' + tar).hide();
                    }
                    if (tar == tab) {
                        tarTab.get(0).CATTAB_SELECT = links[i];
                        $(links[i]).addClass('select');
                    }
                }
                $('#' + tab).show();
            }
        },
        /** 模板替换
        * @param template
        * @param field
        * @example
        * var tpl = "<div><#=TplText#></div><div><#=Link#></div>";
        * $.parseTpl(tpl,{
        *     TplText:'this is tpltext',
        *     Link:'this is link'
        * });
        */
        parseTpl: function (template, field) {//template format
            field = (field === null) ? {} : field;
            var currTpl,
				func = "var func=[];with(obj){func.push('" + template.replace(/[\r\t\n]/g, " ").replace(/\'(?=[^#]*#>)/g, "\t").split("'").join("\\'").split("\t").join("'").replace(/<#=(.+?)#>/g, "',$1,'").split("<#").join("');").split("#>").join("func.push('") + "');}return func.join('');";
            currTpl = new Function("obj", func);
            return currTpl(field);
        },
        /** 转换url参数为JSON
        * @param {String} str 可以为url或者类似于“?param=1&pa2=2”的字符串
        */
        paramJSON: function (str) {
            var s = '&',
                    r = '=',
                    ar, rs = {};
            ar = str.split(s);
            if (str.length > 0) {
                var i = 0, l = ar.length, cur;
                for (; i < l; ++i) {
                    cur = ar[i].split(r);
                    rs[cur[0]] = cur[1];
                }
            }
            return rs;
        },
        /** 将json对象转换为字符串
        * @param value
        * @param [replacer] {Function|Array} can be a function that can replace values, or an array of strings that will select the keys.
        * @param [space] {Number|String} 缩进。定义为数字时将缩进该个数空格，定义为字符串时缩进就为该字符串。
        */
        JSONtostring: function (value, replacer, space) {
            var i;
            var gap = '';
            var indent = '';
            var meta = {    // table of character substitutions
                '\b': '\\b',
                '\t': '\\t',
                '\n': '\\n',
                '\f': '\\f',
                '\r': '\\r',
                '"': '\\"',
                '\\': '\\\\'
            }

            if (typeof space === 'number') { //数字时 缩进为该数目的空格。
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }
            } else if (typeof space === 'string') { //缩进为该字符串
                indent = space;
            }

            // If there is a replacer, it must be a function or an array.
            // Otherwise, throw an error.

            var rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                     typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }
            var quote = function (string) {
                // If the string contains no control characters, no quote characters, and no
                // backslash characters, then we can safely slap some quotes around it.
                // Otherwise we must also replace the offending characters with safe escape
                // sequences.
                var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
                escapable.lastIndex = 0;
                return escapable.test(string) ?
                  '"' + string.replace(escapable, function (a) {
                      var c = meta[a];
                      return typeof c === 'string' ? c :
                          '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                  }) + '"' :
                  '"' + string + '"';
            }
            var str = function (key, holder) {

                // Produce a string from holder[key].

                var i,          // The loop counter.
                  k,          // The member key.
                  v,          // The member value.
                  length,
                  mind = gap,
                  partial,
                  value = holder[key];

                // If the value has a toJSON method, call it to obtain a replacement value.
                if (value && typeof value === 'object' &&
                      typeof value.toJSON === 'function') {
                    value = value.toJSON(key);
                }

                // If we were called with a replacer function, then call the replacer to
                // obtain a replacement value.
                if (typeof rep === 'function') {
                    value = rep.call(holder, key, value);
                }

                // What happens next depends on the value's type.

                switch (typeof value) {
                    case 'string': return quote(value);
                    case 'number':
                        // JSON numbers must be finite. Encode non-finite numbers as null.
                        return isFinite(value) ? String(value) : 'null';
                    case 'boolean':
                    case 'null':
                        // If the value is a boolean or null, convert it to a string. Note:
                        // typeof null does not produce 'null'. The case is included here in
                        // the remote chance that this gets fixed someday.
                        return String(value);
                        // If the type is 'object', we might be dealing with an object or an array or
                        // null.
                    case 'object':

                        // Due to a specification blunder in ECMAScript, typeof null is 'object',
                        // so watch out for that case.

                        if (!value) {
                            return 'null';
                        }

                        // Make an array to hold the partial results of stringifying this object value.

                        gap += indent;
                        partial = [];

                        // Is the value an array?

                        if (Object.prototype.toString.apply(value) === '[object Array]') {

                            // The value is an array. Stringify every element. Use null as a placeholder
                            // for non-JSON values.

                            length = value.length;
                            for (i = 0; i < length; i += 1) {
                                partial[i] = str(i, value) || 'null';
                            }

                            // Join all of the elements together, separated with commas, and wrap them in
                            // brackets.

                            v = partial.length === 0 ? '[]' :
                          gap ? '[\n' + gap +
                                  partial.join(',\n' + gap) + '\n' +
                                      mind + ']' :
                                '[' + partial.join(',') + ']';
                            gap = mind;
                            return v;
                        }

                        // If the replacer is an array, use it to select the members to be stringified.

                        if (rep && typeof rep === 'object') {
                            length = rep.length;
                            for (i = 0; i < length; i += 1) {
                                k = rep[i];
                                if (typeof k === 'string') {
                                    v = str(k, value);
                                    if (v) {
                                        partial.push(quote(k) + (gap ? ': ' : ':') + v);
                                    }
                                }
                            }
                        } else {

                            // Otherwise, iterate through all of the keys in the object.

                            for (k in value) {
                                if (Object.hasOwnProperty.call(value, k)) {
                                    v = str(k, value);
                                    if (v) {
                                        partial.push(quote(k) + (gap ? ': ' : ':') + v);
                                    }
                                }
                            }
                        }

                        // Join all of the member texts together, separated with commas,
                        // and wrap them in braces.

                        v = partial.length === 0 ? '{}' :
                      gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                              mind + '}' : '{' + partial.join(',') + '}';
                        gap = mind;
                        return v;
                }
            }
            // Make a fake root object containing our value under the key of ''.
            // Return the result of stringifying the value.
            return str('', { '': value });
        },
        isString: function (str) {
            var tp = typeof (str),
			rgx = /^undefined|null|NaN$/;
            if (tp === 'string'
		    && !rgx.test(str + '')
		    && isNaN(str * 1)) {
                return true;
            } else {
                return false;
            }
        },
        isNumber: function (str) {
            str = (str + '') * 1;
            var rgx = /^[+-]?\d+([\.]\d+)?$/;
            if (rgx.test(str)) {
                return true;
            } else {
                return false;
            }
        },
        isEmailAddress: function (str) {
            var rgx = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i;
            if (str && rgx.test(str)) {
                return true;
            } else {
                return false;
            }
        },
        isInt: function (str) {
            str = (str + '') * 1;
            var rgx = /^[+-]?\d+$/;
            if (rgx.test(str)) {
                return true;
            } else {
                return false;
            }
        },
        isFloat: function (str) {
            str = (str + '') * 1;
            var rgx = /^([+-]?\d+)(\.\d+)+$/;
            if (rgx.test(str)) {
                return true;
            } else {
                return false;
            }
        },
        isUrl: function (url) {
            var rgx = /^(((?:https?|ftp|news):)\/\/)?([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&amp;]*)?)?(#[a-z][a-z0-9_]*)?$/,
                   rs = false,
                   mc;
            mc = url.match(rgx);
            if (mc) {
                rs = {
                    href: mc[0],
                    host: mc[3],
                    hostname: mc[4] + mc[5],
                    pathname: mc[9] || '' + mc[10] || '',
                    port: undefined,
                    protocol: mc[2],
                    search: mc[12]
                }
            }
            return rs;
        },
        /** 给url获取/添加/修改/删除参数（没有value的时候会返回指定key的值）
        * @param url 需要进行操作的url
        * @param key 需要操作的key
        * @param value 可选，如果有则会进行复制操作（如果为空字符串或者null字符串则删除）
        */
        urlParam: function (url, key, value) {
            if (!key) { return false; }

            //Handle object literals
            if (typeof (key) === 'object') {
                var newurl = url;
                for (var v in key) {
                    newurl = arguments.callee.call(this, newurl, v, key[v]);
                }
                return newurl;
            }

            key = $.trim(key);

            var indexParam = url.indexOf('?'),
			urlPath = url.substr(0, indexParam === -1 ? url.length : indexParam),
			params = indexParam === -1 ? '' : url.substr(indexParam + 1), //orginal param
			tmpParams = params,
			newParams = '',
			rgx, 	//regExp: find key
			rs = ''; //the key's value

            if (value === undefined && typeof (key) === 'string') {//get value

                params = '&' + params;
                params = params.split('&' + key + '=');

                if (params.length >= 2) {
                    rs = params[params.length - 1];
                    rs = rs.substring(0, rs.indexOf('&'));
                }
            } else { //set
                value = $.trim(value);  //encode value

                //remove old key
                rgx = new RegExp('(?:^|\\?|\\&)' + key + '\=([^\\&\\?]*)', 'g'); //regExp: find key
                (params !== '') && (newParams = params.replace(rgx, ''));

                if (value !== '' && value !== null) {
                    newParams = newParams + '&' + key + '=' + encodeURIComponent(value); //add key & value
                }
                newParams = newParams.replace(/^[\&\?]/, ''); //replace first mark

                rs = urlPath + '?' + newParams;
            }

            return rs;
        },
        /** 对指定的字符串应用 HTML 编码,
        * @param {String} html 需要编码的字符串
        */
        htmlEncode: function (html) {
            var div = document.createElement('div'),
                    txt = document.createTextNode(html);
            div.appendChild(txt);
            return div.innerHTML;
        },
        /** 获取、设置cookie
        * @param {String} [name] 默认返回原始cookie字符串
        * @param {String} [value]
        * @param {Object} [settings] 可选json格式，可设置的有encode、expires、path、domain、secure
        * @example
        * $.cookie('userID');     //获取cookie中userID的值
        * $.cookie('userID','myname');  //设置cookie
        */
        cookie: function () {
            var name, value, settings;
            var args = [].slice.call(arguments);
            settings = args[args.length - 1];
            if (typeof (settings) === 'object') {
                args = args.slice(0, -1);
            }
            name = args[0];
            value = args[1];
            settings = $.extend({
                encode: false,
                expires: 30, //expiry time: 30day
                path: '/'
                //domain:,
                //secure:
            }, settings);
            if (value === undefined) {//get
                var ck = document.cookie,
					rs = '';
                if (!ck) { return rs; }
                if (name) {
                    if (ck.length > 0) {
                        var re = new RegExp(name + '\=(.*?)(\;|$)', 'g');
                        rs = re.exec(ck) || '';
                        rs = rs[1] || '';
                    }
                    rs = unescape(rs);
                } else {
                    rs = unescape(ck);
                }
                if (settings.encode) { rs = $.decode(rs); }
                return rs;
            } else {//set
                if (value === '') { $.removeCookie(name); return false; }
                var today = new Date();
                today.setTime(today.getTime());
                settings.expires = settings.expires * 86400000; //(86400000 = 1000 * 60 * 60 * 24)
                var expires_date = new Date(today.getTime() + (settings.expires));
                if (settings.encode) { value = $.encode(value); }
                document.cookie = name + "=" + escape(value) +
								    ((settings.expires) ? ";expires=" + expires_date.toGMTString() : "") +
								    ((settings.path) ? ";path=" + settings.path : "") +
								    ((settings.domain) ? ";domain=" + settings.domain : "") +
								    ((settings.secure) ? ";secure" : "");
            }
        },
        /** 给指定cookie追加值 */
        appendCookie: function (name, value, separate, settings) {	//append new value to "name",if "name" is none,create and set it's value.
            separate = separate || '&';
            var curr = $.cookie(name, settings);
            if (curr) {
                value = curr + separate + value;
            }
            $.cookie(name, value, settings);
        },
        /** 移除指定cookie */
        removeCookie: function (name, settings) {	//remove cookie "name"
            $.cookie(name, '_', { expires: -1 });
        },
        /** 清空Cookie */
        emptyCookie: function () {	//remove all cookie
            var ck = document.cookie,
				rgx = /[^\s;=]*?=([^;]*)(?:;){0,1}/g;
            if (ck) {
                ck = ck.match(rgx);
                var i = 0, l = ck.length, cur;
                for (; i < l; ++i) {
                    cur = ck[i].split('=')[0];
                    $.removeCookie(cur);
                }
            }
        },
        /** 在触发事件的元素上方显示一个Tooltip
        * @param mode 预定义的有loading/error/success， 定义为“error”和“success”时会在700ms后渐隐消失，提示层的className为 'tip-'+mode
        * @param obj 触发事件的元素，默认自动获取，当无法正确获取时建议定义此值。
        * @param fn callback function
        * @returns {Object} 触发事件的元素
        */
        showTooltip: function (mode, obj, fn) {
            mode = mode || 'loading';
            var mtxt = {
                "loading": "loading...",
                "error": "error",
                "success": "success"
            };
            var tipClass = 'tip-' + mode,
                  tipTxt = mtxt[mode] || '',
                  thisEle = obj || $.getEventTarget($.showTooltip) || document.body;
            if (!thisEle) { return false; }
            var createTip = function (tipEle) {
                tipEle.itemTip && $(tipEle.itemTip).remove();
                if (mode !== 'hide') {
                    tipEle.itemTip = $(tipEle).showTip(tipTxt, tipClass);
                    if (mode === 'error' || mode === 'success') {
                        $(thisEle.itemTip).delay(700).fadeOut();
                    }
                }
            };
            createTip(thisEle);
            //execute callback function
            if (fn && typeof (fn) === 'function') {
                fn();
            }

            return thisEle;
        }
    });

    if (!$.prompt && !$.dialog) {//没有加载到dialog模块就降级处理
        $.prompt = { close: function () { } };
        $.dialog = function (msg, mode, callback) {
            if (mode === 'confirm') {
                var v = confirm(msg);
                if (callback) { callback.call({}, v); }
            } else {
                alert(msg);
            }
        }
    }

    $.fn.extend({
        /** lazyLoad
        * @description delays loading of images
        * @param {String} [mode=manual] 模式，可选有auto（img的src属性正常）、manual（img无src属性，而使用lazyload-src代替）
        * @param {String}  [pixelfix] 空白图片路径
        */
        lazyLoad: (function () {
            var _mode = {
                AUTO: 'auto',
                MANUAL: 'manual'	//default mode
            },
			  _options = {
			      attribute: 'lazyload-src',
			      mode: _mode.MANUAL,
			      pixelfix: get_siteinfo.image() + 'error/pixel.gif'
			  };

            var _class = {
                init: function (container, mode, pixelfix) {
                    this.container = container;
                    this.pixelfix = pixelfix || _options.pixelfix;
                    this.mode = (mode || _options.mode).toLowerCase();

                    this.images = this.filterImages();

                    if (this.images.length > 0) {
                        this.initLoadEvent();
                    }
                },
                initLoadEvent: function () {
                    var fn,
					s = this,
					check = function (e) {
					    if (fn) { return false; }

					    //less times execute loadImage()
					    var evType = e.type;  //event type
					    if (evType === 'scroll') {
					        var nowScrolled = $(window).scrollTop(),
								lastScrolled = s.lastScrolled;
					        if (lastScrolled && lastScrolled > nowScrolled) {
					            return false;
					        }
					        s.lastScrolled = nowScrolled;
					    } else if (evType === 'resize') {
					        s.lastScrolled = 0;
					        var nowHeight = $(window).height(),
								lastHeight = s.winViewedHeight;
					        if (lastHeight && lastHeight > nowHeight) {
					            return false;
					        }
					        s.winViewedHeight = nowHeight;
					    }

					    fn = setTimeout(function () {
					        s.loadImage();
					        if (s.images.length === 0) {	//unbind onscroll,onresize
					            $(window).unbind('scroll resize', check);
					        }
					        fn = null;
					    }, 100);
					};

                    $(function () {	//dom ready
                        s.loadImage();
                    });

                    $(window).bind('scroll resize', check);
                },
                filterImages: function () {
                    var imgs = [],
					container = this.container,
					attrName = _options.attribute,
					isAuto = this.mode === _mode.AUTO,
					selector = isAuto ? 'img:not([' + attrName + '])' : 'img[' + attrName + ']';

                    imgs = $(container).find(selector);

                    if (isAuto) {	//auto replace src
                        imgs.attr(attrName, function () {
                            return this.src;
                        }).attr('src', this.pixelfix);
                    }
                    return imgs;
                },
                loadImage: function () {
                    var s = this,
					imgs = s.images,
					attrName = _options.attribute,
					noShow = [],
					scrolltop = s.lastScrolled || $(window).scrollTop(),
					stop = scrolltop + (s.winViewedHeight || $(window).height());

                    var i = 0, cur;
                    for (; cur = imgs[i++]; ) {
                        if (stop > $(cur).offset().top) {
                            cur.setAttribute('src', cur.getAttribute(attrName));
                            cur.removeAttribute(attrName);
                        } else {
                            noShow.push(cur);
                        }
                    }
                    this.images = noShow;
                }
            };

            var LAZY = function (container, mode, pixelfix) {
                if (!(this instanceof arguments.callee)) {
                    return new arguments.callee(container, mode, pixelfix);
                }

                this.init(container, mode, pixelfix);
            };
            LAZY.prototype = _class;

            return function (mode, pixelfix) {
                return this.each(function () {
                    LAZY(this, mode, pixelfix);
                });
            };
        })(),
        /** 选项卡
        * 对HTML有要求：选项卡的开关为<a>，并且它的href属性带有它所控制显隐的id，如：
        * <ul><li><a href="http://www.test.com/root.html#TargetBox">test link</a></li></ul>
        * 上面的test link就控制id="TargetBox"元素的显隐
        */
        catTab: function () { //Module Tabs
            return this.each(function () {
                var links = $(this).find('a'),
				     el = this,
				     selectClass = 'select';
                links.each(function (i) {
                    this.CATTAB_TARGET = $('#' + $(this).attr('href').split('#')[1]);
                    if (i === 0) {
                        this.CATTAB_TARGET.css('display', '');
                        $(this).addClass(selectClass);
                        el.CATTAB_SELECT = this;
                    } else {
                        this.CATTAB_TARGET.css('display', 'none');
                    }
                })
					  .click(function (e) {
					      e.preventDefault();
					      this.blur();
					      if (el.CATTAB_SELECT) {
					          $(el.CATTAB_SELECT.CATTAB_TARGET).css('display', 'none');
					          $(el.CATTAB_SELECT).removeClass(selectClass);
					      }
					      $(this).addClass(selectClass);
					      $(this.CATTAB_TARGET).css('display', '');
					      el.CATTAB_SELECT = this;
					  });
            });
        },
        /** 根据给定的对象来显示一个提示，event对象会显示在鼠标处，DOM Element会显示在它的上方。<br /> $.showToolTip()的核心方法
        * @param {String} msg 要显示的信息文本
        * @param {String} className 提示层的class，默认为 tip-msg
        */
        showTip: function (msg, className) {//show tip by element
            var _el = $(this).get(0);
            //create tip DOM
            msg = msg || 'done';
            className = className || 'tip-msg';
            var tip = $('<div class="' + className + '">' + msg + '</div>');
            if (_el.tagName) {//DOM element
                _el = $(_el);
                var offset = _el.offset(),
			    inaY = _el.outerHeight();
                if (offset.top * 1 >= inaY * 1) {
                    offset.top = offset.top * 1 - inaY * 1;
                }
                tip.css({
                    position: "absolute",
                    top: offset.top + 'px',
                    left: offset.left + 'px'
                });
            } else if (typeof (_el) === 'object') {//Event
            }
            $('body').append(tip);
            return tip;
        },
        tip: function (e, args) {	 //mouse tooltip
            args = args || '';
            var o = $(this);
            var objH = o.outerHeight(),
				objW = o.outerWidth(),
				winH = $(window).height(),
				winW = $(window).width(),
				sTop = $(window).scrollTop(),
				sLeft = $(window).scrollLeft(),
				eTop = e.clientY || Math.abs(args.offsetY) || 0,
				eLeft = e.clientX || Math.abs(args.offsetX) || 0,
				fixTop = args.offsetY || 6,
				fixLeft = args.offsetX || 6,
				y = eTop + sTop,
				x = eLeft + sLeft;
            var yc = (eTop + objH + fixTop) - winH,
				xc = (eLeft + objW + fixLeft) - winW;
            if (yc > 0) { y = y - yc - fixTop; }
            if (xc > 0) { x = x - objW - (fixLeft * 2); }

            x = x + fixLeft;
            y = y + fixTop;
            o.css({
                top: y + 'px',
                left: x + 'px'
            });
        },
        ajaxLoad: function (args) {//load html by ajax
            /*--args:
            container:wrap HTML's element
            url:The URL of the page to load. if hyperlink,default is "href"
            event:event type
            callback:A function to be executed whenever the data is loaded successfully.
            msgLoading:tip text when loading , default value:Loading
            msgSuccess:show tip text when success , default value:Success
            msgError:show tip text when error , default value:Load Error!
            --*/
            return this.each(function () {
                args = args || '';
                //create tip message
                var _self = $(this),
					tip = [$('<div class="tip-loading">' + (args.msgLoading || 'Loading') + '</div>'), $('<div class="load-page">' + (args.msgLoading || 'Loading') + '<s></s></div>')];

                //event type
                var evtype = {
                    'select': 'change',
                    'a': 'click'
                };
                //define defualt url
                var tag = this.tagName.toLowerCase(),
			    url = args.url;
                if (tag === 'a' && !url) {
                    url = _self.attr('href');
                }

                var ajax = function (url, container, tip, args) {
                    $.ajax({
                        'url': url,
                        'beforeSend': function () {
                            if (args.beforeSend) {
                                (args.beforeSend)({ value: args.value || '' });
                            }
                        },
                        success: function (html) {
                            container.empty().append(html);
                            tip.attr('class', 'tip-success').html(args.msgSuccess || 'Success');
                            setTimeout(function () {
                                tip.fadeOut();
                            }, 300);
                            if (args.callback) {
                                args.callback({ value: args.value || '' });
                            }
                        },
                        error: function () {
                            tip.attr('class', 'tip-error').html(args.msgError || 'Load Error!');
                            setTimeout(function () {
                                tip.fadeOut().remove();
                            }, 2000);
                        }
                    });
                };
                if (!evtype[tag]) {
                    args.container = _self;
                    tip = tip[1];
                    args.container.html(tip);
                    ajax(url, args.container, tip, args);
                } else {
                    tip = tip[0];
                    _self.bind(evtype[tag], { tag: tag, tip: tip, url: url, args: args }, function (event) {
                        event.preventDefault();
                        var tag = event.data.tag,
							tip = event.data.tip,
							url = event.data.url,
							args = event.data.args,
							container = args.container,
							svalue = $(this).val() || '';
                        container = $(container).size() ? $(container) : $('#' + container);

                        var offset = $(this).offset();
                        offset.top = offset.top - 22;
                        tip.css({ position: 'absolute', zIndex: '999', top: offset.top + 'px', left: offset.left + 'px' });

                        tip.appendTo($('body'));
                        if (tag === 'select') {
                            url = $.parseTpl(url, { key: svalue });
                        }
                        args.value = svalue;
                        ajax(url, container, tip, args);
                    });
                }

            });
        },
        ajaxLoadMastlayer: function (args) {//load html by ajax
            /*--args:
            container:wrap HTML's element
            url:The URL of the page to load. if hyperlink,default is "href"
            event:event type
            callback:A function to be executed whenever the data is loaded successfully.
            msgLoading:tip text when loading , default value:Loading
            msgSuccess:show tip text when success , default value:Success
            msgError:show tip text when error , default value:Load Error!
            --*/
            return this.each(function () {
                args = args || '';
                //create tip message
                var _self = $(this), offset
                tip = [$('<div class="tip-loading">' + (args.msgLoading || 'Loading') + '</div>'), $('<div class="load-page">' + (args.msgLoading || 'Loading') + '<s></s></div>')];

                //event type
                var evtype = {
                    'select': 'change',
                    'a': 'click'
                };
                //define defualt url
                var tag = this.tagName.toLowerCase(),
			    url = args.url;
                if (tag === 'a' && !url) {
                    url = _self.attr('href');
                }

                var ajax = function (url, container, tip, args) {
                    $.ajax({
                        'url': url,
                        'beforeSend': function () {
                            if (args.beforeSend) {
                                (args.beforeSend)({ value: args.value || '' });
                            }
                        },
                        success: function (html) {
                            container.empty().append(html);
                            //hide masklayer
                            setTimeout(function () {
                                $(".masklayer").fadeOut().remove();
                            }, 100);

                            if (args.callback) {
                                args.callback({ value: args.value || '' });
                            }
                        },
                        error: function () {
                            //hide masklayer
                            setTimeout(function () {
                                $(".masklayer").fadeOut().remove();
                            }, 100);

                            // show and hide tip
                            tip.attr('class', 'tip-error').html(args.msgError || 'Load Error!').appendTo('body').hide();
                            tip.css({ 'position': 'absolute', 'z-index': '999', 'top': offset.top + 'px', 'left': offset.left + 'px' }).fadeIn("fast");

                            setTimeout(function () {
                                tip.fadeOut().remove();
                            }, 1000);
                        }
                    });
                };
                if (!evtype[tag]) {
                    args.container = _self;
                    tip = tip[1];
                    args.container.html(tip);
                    ajax(url, args.container, tip, args);
                } else {
                    tip = tip[0];
                    _self.bind(evtype[tag], { tag: tag, tip: tip, url: url, args: args }, function (event) {
                        event.preventDefault();
                        var tag = event.data.tag,
							tip = event.data.tip,
							url = event.data.url,
							args = event.data.args,
							container = args.container,
							svalue = $(this).val() || '';
                        container = $(container).size() ? $(container) : $('#' + container);

                        $("<div class='masklayer'></div>").hide().appendTo('body').fadeTo("fast", 0.5);
                        $("<div class='tip-offset'></div>").appendTo($(this).parent());
                        var tipTop = -(22 - $(this).height()) / 2;
                        var tipLeft = $(this).width() + 20;
                        $(".tip-offset").css({ position: 'absolute', zIndex: '999', top: tipTop + 'px', left: tipLeft + 'px' });
                        offset = $(".tip-offset").offset();
                        $(".tip-offset").remove();

                        if (tag === 'select') {
                            url = $.parseTpl(url, { key: svalue });
                        }
                        args.value = svalue;
                        ajax(url, container, tip, args);
                    });
                }

            });
        },
        /** auto hide line
        * @param
        */
        autoHideLine: function (showLine, lineHeight, childTag) {
            var _moreClick = function (pa, h, classfew) {
                var c = pa.css('height');
                if (parseNumber(c) > h) {
                    pa.css('height', h + 'px');
                    $(this).removeClass(classfew).text('see all');
                } else {
                    pa.css('height', 'auto');
                    if (get_siteinfo.enableCustomCode() === 'true') {
                        ES.callbackTuple.execute('SeeAllClick', get_siteinfo.pagetype(), 'Quick_Link', 'SeeAll');
                    }
                    $(this).addClass(classfew).text('see fewer');
                }
                return false;
            };
            return this.each(function () {
                childTag = childTag || 'li';
                var $s = $(this),
				   h = showLine * lineHeight,
				   class_seeAll = 'link-seeall',
				   class_seeFew = 'link-seefew',
				   childNum = $s.find(childTag).length,
				   linkMore;

                if (childNum > showLine) {
                    linkMore = $('<a href="#" title="" class="' + class_seeAll + '">see all</a>');
                    linkMore.click(function () {
                        return _moreClick.call(this, $s, h, class_seeFew);
                    });
                    $s.css({
                        height: h + 'px',
                        overflow: 'hidden'
                    }).after(linkMore);
                }
            });
        }
    });
})(jQuery);

(function ($, window) {
    var ES = {
        clone: function (obj) {
            var F = function () { };
            F.prototype = obj;
            return new F();
        },
        /** item page "Share This Product" handle*/
        ShareLink: {
            init: function (e) {//should bind init() to links' container element
                var tar = e.target,
				     cn = tar && tar.className,
				     shareFn = {
				         email: 'email',
				         twitter: 'twitter',
				         facebook: 'facebook'
				     },
					fn = shareFn[cn];
                if (fn) {
                    e.preventDefault();
                    ES.ShareLink[fn].call();
                }
            },
            url: {
                email: get_siteinfo.root() + 'item/email/',
                twitter: 'http://twitter.com/share',
                facebook: 'http://www.facebook.com/share.php'
            },
            getItem: function () {	 //get item's info: url,title
                var url = encodeURIComponent(location.href),
					title = encodeURIComponent($("#ItemTitleSpan").text());
                return {
                    url: url,
                    title: title
                };
            },
            email: function () {
                var info = ES.ShareLink.getItem(),
					url = ES.ShareLink.url.email + '?itemPageUrl=' + info.url + '&subject=' + info.title;

                window.open(url, "ShareItem", "width=520, height=500");
            },
            twitter: function () {
                var info = ES.ShareLink.getItem(),
					url = ES.ShareLink.url.twitter + '?url=' + info.url + '&text=' + info.title;

                window.open(url, "ShareItem", "width=540, height=400");
            },
            facebook: function () {
                var info = ES.ShareLink.getItem(),
					url = ES.ShareLink.url.facebook + '?u=' + info.url + '&t=' + info.title;

                window.open(url, "ShareItem", "width=800, height=400");
            }
        },
        //set google track
        ggTrack: function (trackType) {
            var args = [].slice.call(arguments),
				trackArg = args.slice(1);
            _gaq.push([trackType].concat(trackArg));
        },
        /** 校验item的instoreQty，主函数是checkCartHandle.init
        * @param {JSON} setting 配置参数：
        * imgSelector:匹配add cart按钮的jquery选择器
        * imgIdFix:add cart按钮的id前缀
        * itemNums:多个itemNum使用^拼接
        * afterbuild:ajax获取数据成功后需执行的函数，有buttonElement,qty,itemNum,status这几个参数
        * addToCart:使用该函数替换默认的add to cart事件，有一个itemNum参数
        */
        checkCartHandle: {
            /** initialization item handle:
            * 1. ajax query item qty;
            * 2. bind button's click event;
            */
            init: function (args) {
                if (!args.itemNums) { return false; }
                var that = ES.checkCartHandle,
					callee = arguments.callee,
					time = that._ajaxTime || 0;
                //get qty
                $.ajax({
                    type: 'GET',
                    cache: false,
                    url: get_siteinfo.root() + 'item/status?items=' + $.encode(args.itemNums),
                    success: function (da) {
                        time = that._ajaxTime = time + 1;
                        if (da * 1 === -1 && time < 5) {//error
                            setTimeout(callee, 150);
                        } else {
                            that.buildBtn(da, args);
                        }
                    }
                });

                //bind event
                that._initEvent(args);
            },
            _initEvent: function (args) {
                var that = ES.checkCartHandle;
                $(args.imgSelector).bind('click', function () {
                    var s = $(this),
						qty = s.attr('data-qty') * 1,
						num = s.attr('data-itemNum');
                    if (isNaN(qty)) { return false; }

                    if (qty > 0) {
                        args.addToCart ? args.addToCart(num, args) : that.addToCart(num, args);
                    } else {
                        args.notify ? args.notify(num) : that.notify(num);
                    }
                });
            },
            buildBtn: function (data, args) {
                var callee = arguments.callee,
					that = ES.checkCartHandle;
                if ($.isArray(data) && data.length > 0) {
                    var i = 0, cur;
                    for (; cur = data[i++]; ) {
                        callee.call(that, cur, args);
                    }
                    return false;
                }
                //Add .toUpperCase() by kevin 20110826 for on 47 the letter is in lower case
                var num = data.ItemNum.toUpperCase(),
					qty = data.InstockQty * 1,
					status = data.OnOffStatus * 1,
                    ShipStatus = data.ShipInternational,

					el = $('#' + args.imgIdFix + num),
					tag = el.length > 0 ? el.get(0).tagName : '';
                if (status == 2) { qty = 0; }
                if (status <= 0) {
                    $('#WishItem_' + num).remove();
                    $('#SavedItem_' + num).remove();
                    $('#RecentlyViewedItem_' + num).remove();
                    return false;
                }

                el.attr('data-qty', qty).attr('data-itemNum', num);
                if (qty > 0 && status === 1) {// add to cart
                    tag === 'IMG' ? el.attr('src', get_siteinfo.image() + 'btn_addtocart.gif') : '';
                } else {	//notify
                    tag === 'IMG' ? el.attr('src', get_siteinfo.image() + 'link-notify2.gif') : '';
                }
                if (args.afterbuild) {
                    args.afterbuild(el, qty, num, status);
                }

                if (!ShipStatus) {  // For Add to Cart Stauts
                    AddToCartStyleChange("addlist-" + num, 1);
                }

            },
            addToCart: function (itemNum, args) {
                var qtybox = (args && args.qtyBoxFix) ? $('#' + args.qtyBoxFix + itemNum) : [],
					qty = qtybox.length > 0 ? qtybox.val() : 1;
                if (qty * 1 > 0) {
                    cart.add(itemNum);
                } else {
                    $.dialog("Quantity must be number and greater than 0");
                    return false;
                }
            },
            notify: function (itemNum) {
                autoNotify && autoNotify(itemNum);
            }
        },
        /** 回调函数管理 */
        callbackTuple: {
            /** add callback tuples
            * @param {String} name
            * @param {Function} callbacks 从第二个参数开始的function都会添加进指定名称的元组里
            * @return {Array} 该tuple列表
            */
            add: function (name) {
                if (typeof (name) !== 'string') {
                    for (var i in name) {
                        arguments.callee.apply(this, [i].concat(name[i]));
                    }
                    return false;
                }
                var storeName = '__' + name + '__',
					tuple = this[storeName] || [],
					callbacks = [].slice.call(arguments).slice(1);

                var i = 0, l = callbacks.length;
                for (; i < l; ++i) {
                    tuple.push(callbacks[i]);
                }

                this[storeName] = tuple;

                return tuple;
            },
            /** get callback tuple
            * @param {String} name 需要获取的元组列表
            * @return {Array} 指定的元组列表
            */
            get: function (name) {
                var tuple = this['__' + name + '__'] || [];
                return tuple;
            },
            /** execute tuples
            * @param {String} name
            */
            execute: function (name) {
                var tuples = this.get(name).concat([]),
					args = [].slice.call(arguments).slice(1);
                while (tuples && tuples.length) {
                    tuples.shift().apply('', args);
                }
            }
        }
    };
    window.ES = ES;
})(jQuery, window);


//Click banner(foot) with google track
function bannerTracking(arg) {
    try {
        _gaq.push(['_trackPageview', arg]);
    } catch (err) { }
}
//click banner(top) with google track
function outboundLinkTracking(link, category, action) {
    try {
        _gaq.push(['_trackEvent', category, action]);
        setTimeout('document.location = "' + link.href + '"', 100);
    } catch (err) { }
}

function recordOutboundLink(link, category, action) {
    try {
        _gat._getTrackerByName()._trackEvent(category, action);
        setTimeout(window.open('' + link.href, 'mywin',
'left=20,top=20,width=500,height=500,toolbar=1,resizable=1'), 100);
    }
    catch (err) { }
}
/*-- ES custom
(function ($,window) {
var ES = {
user_info:user_info,
ui_config:ui_config,
item_info:item_info,
recently_search:recently_search,
HAS_LOGIN:HAS_LOGIN,
goLogin:function (reply) {
var win = top||window;
reply = reply || win.location.href;
var newHref = get_siteinfo.root() + 'member/signin'+'?reply='+encodeURIComponent(reply);
win.location.href = newHref;
},
cart:cart,
wishList:wishList,
recently:recently,
autoNotify:function(itemNum) {
var thisObj = $.getEventTarget($.getEvent(autoNotify));
var box = $('<div class="notify-dialog">'+
'<h3 class="title-notify">Auto Notification <span class="dialog-close" onclick="TB_remove()">close</span></h3>'+
'<div class="entry">'+
'<p class="tip">Please enter your email address below. You will receive an email notification once this item becomes available for purchase.</p>'+
'<div class="form-email">'+
'<form action="/item/notifyme" method="post"><input id="ItemNum" name="ItemNum" type="hidden" value="'+itemNum+'">'+
'<label>Email Address:</label><input class="input-text" name="AutoNotificationEmail" type="text" value=""> <input type="submit" class="btn-submit" name="ANSumbit" value=" ">'+
'<div class="notifyMsg"><span></span></div>'+
'</form>'+
'</div>'+
'<p class="tip-note"><strong>Note:</strong> Due to limited supply, all stock is sold on a first-come first-serve basis. Auto Notification does not guarantee availability or price. <br>All prices are subject to change without notice. </p>'+
'</div>'+
'</div>');
box.find('form').validate({
rules: {
AutoNotificationEmail: {
required: true,
email: true
}
},
errorLabelContainer: box.find('div.notifyMsg span'),
highlight: function(element, errorClass) { $(element).addClass(errorClass); },
unhighlight: function(element, errorClass) { $(element).removeClass(errorClass); },
messages: {
AutoNotificationEmail: {
required: "Email is required.",
email: "Please input a valid email adress."
}
},
submitHandler:function(f) {
var data = $(f).serialize();
var url = $(f).attr("action");
$.ajax({
type: "POST",
url: url,
dataType: "JSON",
data: data,
success: function(d) {
if (d === "true") {
TB_remove();
$.showTooltip('success',thisObj);
}
},
error: function(msg) { alert(msg) }
});
return false;
}
});
var tmpWrap = $('<div id="autoNotifyWrapTemp"></div>');
tmpWrap.hide().append(box).appendTo($('body'));
TB_show('','#TB_inline?height=171&width=518&modal=true&inlineId=autoNotifyWrapTemp');
tmpWrap.remove();
}
};
window.ES = ES;
})(jQuery,window);
--*/


/** @ignore */
/** cookie管理
* 提供两个参数：
* key:需要进行操作的cooki key
* value:可选，给指定key设定的值
* （赋值的时候不会删除旧值，而是使用^符号连接新值）
*/
var CookieManager = function (setting) {
    var _settings = $.extend({
        separate: '^',
        encode: true,
        readonly: false
        //mode:    字符串格式，可选有json，默认为param
        //cookieName:
        //abbr:	全称对应的简写
        //max:   最多存储的个数
    }, setting);
    var cm = function (key, value) {
        var ui_key = _settings.cookieName,
                  ui = $.cookie(ui_key, _settings),
                  abbr = _settings.abbr || {},
                  sep = _settings.separate;
        key = (key || '').toLowerCase();
        key = abbr[key] || key;
        var uiobj = {},  //cookie值字面量
                  rgx = new RegExp('[^\\s\\' + sep + '=]+=[^=\\' + sep + ']*', 'g'), //单条 “属性=值”
                  maxNum = _settings.max && _settings.max * 1,
                  isJsonData = _settings.mode && _settings.mode.toLowerCase() === 'json';

        uiobj = ui && (isJsonData ? $.parseJSON(ui) : (function () {  //转换成字面量
            var rs = ui.match(rgx) || '',
                        i = 0, l = rs.length,
                        temp, ui_temp = {};
            for (; i < l; ++i) {
                temp = rs[i].split('=');
                ui_temp[temp[0]] = temp[1];
            }
            rs = ui_temp;
            return rs;
        })());

        if (value === undefined) {//get key
            if (!key) {
                return uiobj;
            } else {
                return uiobj[key];
            }
        } else if (!_settings.readonly) {//set key
            if (!isJsonData) {
                if (uiobj[key] !== undefined) {     //已存在，删除
                    var re = new RegExp('(\\' + sep + '|^)' + key + '=[^=\\' + sep + ']*', 'g');
                    ui = ui.replace(re, '');
                }
                //添加新值
                ui = ui + sep + (key + '=' + value);
                ui = ui.replace(new RegExp('^\\' + sep), '');

                if (maxNum) {    //截取最大值
                    var ui_tmp, ui_ln;
                    ui_tmp = ui.split(sep);
                    ui_ln = ui_tmp.length;
                    if (ui_ln > maxNum) {
                        ui_tmp = ui_tmp.slice(ui_ln - maxNum);
                        ui = ui_tmp.join(sep);
                    }
                }
            } else {
                uiobj[key] = value;
                ui = $.JSONtostring(uiobj);
            }

            $.cookie(ui_key, ui, _settings);
            return value;
        }
    };
    return cm;
};
/** 用户信息
* @class user_info
* @description 获取cookie中的用户信息
* @param {String} key 想要获取的用户信息名称.<br />可以使用这些缩写词：<br />
<table>
<tr><th>全名</th><th>写进cookie的名称</th></tr>
<tr><td>memberid</td><td>mid</td></tr>
<tr><td>userid</td><td>uid</td></tr>
<tr><td>email</td><td>eml</td></tr>
</table>
* @param {String} value UI key 的值
* @example
* user_info('memberid');     //get memberid's value
*/
var user_info = CookieManager({
    cookieName: 'u',
    readonly: true,
    abbr: {
        memberid: 'mid',
        userid: 'uid',
        email: 'eml'
    }
});
/** 网站界面UI配置
* @ignore
* @class ui_config
* @description 获取/设置网站界面UI设置(cookie)
* @param {String} key 想要获取的UI key.<br />可以使用这些缩写词：<br />
<table>
<tr><th>全名</th><th>写进cookie的名称</th></tr>
<tr><td>sortby</td><td>sb</td></tr>
<tr><td>pagesize</td><td>ps</td></tr>
<tr><td>gridstyle</td><td>vs</td></tr>
<tr><td>dialogshow</td><td>sc</td></tr>
</table>
* @param {String} value UI key 的值
* @example
* ui_config('sortby');     //get sortby's value
* ui_config('sortby','1');    //set sortby=1
*/
var ui_config = CookieManager({
    cookieName: 'uc',
    data: 'json',
    abbr: {
        sortby: 'sb', //Sortby
        pagesize: 'ps', //Page size
        gridstyle: 'vs', //viewitemstyle
        dialogshow: 'sc'	//show cart summary
    }
});
/** 存储item最后更新时间 */
var item_info = CookieManager({
    cookieName: 'ii',
    abbr: {
        mycart: 'cl',
        wishlist: 'wl',
        recently: 'rv'
    }
});
/** 存储最近的5个搜索记录 */
var recently_search = CookieManager({
    cookieName: 'rs',
    max: 5
});
/** 用户是否登录
* @returns {Boolen} 用户登录状态，已登录返回true
*/
var HAS_LOGIN = (function () {
    var mid = user_info('uid'),
		tkn = $.cookie('tkn');
    if (mid && tkn) {
        return true;
    }
    return false;
})();
/** 跳转至登录页面
* @param reply 登陆成功后redirect link，默认为location.href
*/
var goLogin = function (reply) {
    var win = top || window;
    reply = reply || win.location.href;
    var newHref = get_siteinfo.root() + 'member/signin' + '?reply=' + encodeURIComponent(reply);
    win.location.href = newHref;
};
/** @namespace */
/**
* item管理类
* 每个子类提供默认的三个方法：
* add(arguments)
* update(arguments)
* remove(arguments)
* arguments参数列表根据子类的defaultData设定
* 子类添加新的方法可以设定handle对象
*/
var ItemManager = function (settings) {
    var _options = $.extend({
        separateData: '^', //item中每个数据的分隔符
        separateItem: '~', //每条item的分隔符
        currency: '$', //currency sign
        doIni: true, //initialize or dont
        needLogin: false,
        innerBox: 'div.wrap-item', //item wrap's selector
        dialogClose: 'span.dialog-close', //close button's selector
        imageSize: '50x50',
        classNoitem: 'dialog-noitem',
        updateMod: 'replace', //update方法更新item的方式，默认为“replace”覆盖原有的数据，可选的有：“rebuild”-删除原来数据再进行更新
        order: 'asc', //排序显示，默认为正序(asc)，可选的有 倒序（desc）
        emptyMsg: '<p>There are NO items</p>',
        liveupdate: true
        //hookID:,	//触发打开dialog的button jq选择器
        //cookie:如果设置值即开启写入cookie，值作为cookie name使用(cart、wish_list、recently)
        //ajaxPost:	//使用ajax方式添加数据，如果没有则写入cookie
        //ajaxGet:	//读取ajax的数据，如果没有则读取cookie
        //template:模板
        //beforeAdd,afterAdd,successAdd,errorAdd:各种添加时触发的事件
        //beforeRemove,afterRemove,successRemove,errorRemove:各种删除时触发的事件
        //beforeBuild,afterBuilt,successBuild,errorBuild：各种build时触发的事件
    }, settings);

    var _SLICE = [].slice;

    var _boxID = _options.hookID + 'Item_';
    var _elements = {};
    var _emptyMsg = $(_options.emptyMsg);
    var _needBuild = true;
    var _dialogShow = '';
    var _handle = _options.handle || { add: '', update: '', remove: '' }; //default handle:add,update,remove
    /*--
    var _defData = {	//default data format
    'add':['String', 'String', 'Price','Int'],	//(itemNum,Title,Price,Qty)
    'normal':['String','String','Price','Int'],		//(itemNum,Title,Price,Qty)
    'update':['String','Int'],	//(itemNum,Qty)
    'remove':['String']		//(itemNum)
    };
    --*/
    var _defData = {	//default data format
        'add': ['-', '-', '-', 1], //(itemNum,Title,Price,Qty)
        'normal': ['-', '-', '-', 1], 	//(itemNum,Title,Price,Qty)
        'update': ['-', 1], //(itemNum,Qty)
        'remove': ['-']		//(itemNum)
    };
    var _fixData = {
        'isString': function (s) {
        },
        'isFloat': function (s) {
        },
        'isInt': function (s) {
        },
        'isPrice': function () {
        }
    };

    var _class = {	//private class
        init: function () {
            if (_options.hookID && $('#' + _options.hookID).length) {
                _elements.link = $('#' + _options.hookID);
                _elements.dialog = $('#Dialog' + _options.hookID);
                _elements.box = (_elements.dialog).find(_options.innerBox);
                if (_elements.link.length) {
                    _class.initHook();
                    _class.initBuild();
                }
            } else {
                _elements = undefined;
            }
            if (_options.afterinit) { (_options.afterinit).call(im, _elements); }
        },
        initHook: function () {
            //onpen dialog
            $(_elements.link).click(function (e) {
                e.preventDefault();
                if (!_dialogShow) {
                    im.show();
                } else {
                    im.hide();
                }
            }).add(_elements.dialog).hover(function () {
                clearTimeout(_dialogShow);
                _dialogShow = '';
            }, function () {
                _dialogShow = setTimeout(function () { im.hide(); }, 150);
            });
            //close button
            (_elements.dialog).find(_options.dialogClose).click(function () {
                im.hide();

            });
        },
        initBuild: function () {
            var shouldBuild = (function () {
                var hasCookie = _options.cookie ? ($.cookie(_options.cookie) !== '' ? $.cookie(_options.cookie) : false) : false;
                if ((hasCookie || !_options.needLogin) || (_options.needLogin && HAS_LOGIN)) {
                    return true;
                }
                return false;
            })();
            if (shouldBuild) {
                _class.buildList();
            } else {
                _class.showEmptyMsg();
            }
        },
        /** add/remove/update Item in Cookie & Server
        * @param data {JSON} item's json data
        * @param mode {String} method:add/remove/update
        */
        saveItem: function (data, mode) {

            var ajaxUrl = _options[mode + 'Url'] || _handle[mode]['url'] || _handle[mode],
			needLogin = _handle[mode]['needLogin'] || _options.needLogin || false,
			beforeCallBack = _options['before' + mode],
			afterCallBack = _options['after' + mode];

            //format data to string
            var res,
			newItemStr = [],
			pa = _handle[mode]['param'] || _options["param"],
			paramplus = _handle[mode]['paramplus'];
            paramplus = paramplus ? '&' + paramplus : '';

            for (res in data) {
                data[res].unshift(res);
                //newItem.push(data[res]);
                newItemStr.push(data[res].join(_options.separateData));
            }
            newItemStr = newItemStr.join(_options.separateItem);
            newItemStr = $.encode(newItemStr);

            var urlParam = pa + '=' + newItemStr + paramplus;

            if (!_options.cookie && needLogin && ajaxUrl && !HAS_LOGIN) {
                goLogin(ajaxUrl + "?" + urlParam);
                return false;
            }

            if (ajaxUrl) { //post to server
                var tooltip = _class.showTooltip('loading');
                $.ajax({
                    url: ajaxUrl,
                    type: "POST",
                    data: urlParam,
                    dataType: 'json',
                    success: function (state) {
                        //state: -1:Failed,0:UnLogin,1:Success,
                        if (state === 0 && needLogin) {
                            goLogin(ajaxUrl + "?" + urlParam);
                            return false;
                        } else if (state === 1) {
                            if (beforeCallBack) { beforeCallBack.call(im, $.decode(newItemStr), _elements); }
                            _class.showTooltip('success', tooltip);
                            _needBuild = true;
                            _options.hookID && item_info(_options.hookID.toLowerCase(), (new Date).getTime());
                            if (afterCallBack) { afterCallBack.call(im, $.decode(newItemStr), _elements); }
                        } else {
                            _class.showTooltip('error', tooltip);
                        }
                    },
                    error: function (e) { _class.showTooltip('error', tooltip); }
                });
            } else if (_options.cookie && !ajaxUrl) {//save to cookie
                newItemStr = $.decode(newItemStr);
                var cc = $.cookie(_options.cookie),
                              oldItem = {};
                if (cc) {	//has old item
                    var tmpItem = cc.split(_options.separateItem); //total item array
                    var i = 0, l = tmpItem.length,
                                    tmp, //single item array
                                    rgx = function (key) {    //find item
                                        return new RegExp('(?:^|' + _options.separateItem + ')' + key + '[^\\' + _options.separateItem + ']*', 'g');
                                    };
                    for (; i < l; ++i) {
                        tmp = tmpItem[i].split(_options.separateData);
                        oldItem[tmp[0]] = tmp.slice(1);
                        if (data[tmp[0]] !== undefined) {
                            if (mode === 'add') {//adding number
                                //data[tmp[0]];
                            }
                            cc = cc.replace(rgx(tmp[0]), ''); // delete the repeat item;
                        }
                    }
                    cc = cc + _options.separateItem;
                }
                cc = cc + newItemStr;
                cc = cc.replace((new RegExp('^\\' + _options.separateItem)), ''); //delete first separate
                $.cookie(_options.cookie, cc);
                if (_options.afterSaveCookie) { _options.afterSaveCookie.call(im, cc, _elements); }
            }
        },
        /** build HTML of items
        * @example
        */
        getItemHTML: function (data) {
            var html = '';
            var id = data.ItemNum,
				title = data.Title,
				price = (data.Price * 1).toFixed(2),
				qty = data.Qty,
				boxID = _boxID + id,
				linkParam = data.Param || '';
            var shorttitle = title.length > 100 ? title.slice(0, 100) + '...' : title,
			seotitle = shorttitle.replace(/&reg;/g, "").replace(/[^a-zA-Z0-9\-]/g, '-').replace(/[\-]{2,}/g, '-').replace(/\-$/g, ''),
			pic = get_siteinfo.objectimage(id, 'item', _options.imageSize),
			link = get_siteinfo.root('http:') + 'product/' + seotitle + '/' + id + linkParam,
			tprice = price.indexOf(_options.currency) !== -1 ? price : _options.currency + price;

            html = $.parseTpl(_options.template, { id: id, idfix: id.toUpperCase(), boxID: boxID, title: title, shorttitle: shorttitle, price: tprice, qty: qty, pic: pic, link: link });
            return html;
        },
        getItemNum: function () {
            return $.arrayUnique(_class._ItemNum);
        },
        buildList: function () {
            if (!_elements) { return false; }
            var that = _class;
            _class.showEmptyMsg();

            that._ItemNum = $.arrayUnique(that._ItemNum || []);

            if (_options.getUrl) {//from ajax
                var boxtip = _class.boxLoading('load');
                //$(_elements.box).css('height','');
                _elements && _elements.box && _elements.box.html(boxtip);
                var url = _options.getUrl,
                              infoKey = _options.hookID.toLowerCase();
                timePlus = item_info(infoKey);
                if (!timePlus || infoKey == "mycart") {
                    timePlus = item_info(infoKey, (new Date).getTime());
                }
                url = $.urlParam(url, '_', timePlus + '_' + (user_info('memberid') || '') + ($.cookie('tkn') || '') + '_' + $.cookie('coc')); //add memberid for fix SignIn
                $.ajax({
                    url: url,
                    type: "GET",
                    cache: true,
                    dataType: 'json',
                    success: function (data) {
                        _needBuild = false; //dont build agaiin;
                        if (data && data * 1 !== 0) {

                            var info = '', jsonInfo;
                            if (_options.jsonInfo !== undefined) {
                                jsonInfo = data.slice(_options.jsonInfo, 1);
                                data.splice(_options.jsonInfo, 1);
                            }
                            if (_options.order === 'desc') {
                                data = data.reverse();
                            }
                            var html = [];
                            var i = 0, l = data.length;
                            for (; i < l; ++i) {
                                //store itemNum
                                that._ItemNum.push(data[i].ItemNum);

                                html.push(_class.getItemHTML(data[i]));
                            }
                            //                            boxtip.fadeOut(function () {
                            //                                if (html.length > 0) {
                            //                                    _class.hideEmptyMsg();
                            //                                    _elements.box && _elements.box.html(html.join(''));
                            //                                    if (html.length > 3) {//set box height
                            //                                        var box = $(_elements.box),
                            //                                                             hideBox = box.add(box.parents()).filter(function (index) {
                            //                                                                 return $(this).css('display') === 'none';
                            //                                                             }),
                            //                                                             bh = 0;
                            //                                        hideBox.show();
                            //                                        box.find('> *').slice(0, 3).each(function () {
                            //                                            bh += $(this).outerHeight(true);
                            //                                        });
                            //                                        hideBox.hide();
                            //                                        if (bh > 0) { box.css({ height: bh + 'px', overflow: 'auto' }); }
                            //                                    } else { _elements.box.css({ 'height': 'auto' }); }
                            //                                } else {
                            //                                    _class.showEmptyMsg();
                            //                                }
                            //                            });
                            if (html.length > 0) {
                                _class.hideEmptyMsg();
                                _elements.box && _elements.box.html(html.join(''));
                                if (html.length > 3) {//set box height
                                    var box = $(_elements.box),
                                           hideBox = box.add(box.parents()).filter(function (index) {
                                               return $(this).css('display') === 'none';
                                           }),
                                           bh = 0;
                                    hideBox.show();
                                    box.find('> *').slice(0, 3).each(function () {
                                        bh += $(this).outerHeight(true);
                                    });
                                    hideBox.hide();
                                    if (bh > 0) { box.css({ height: bh + 'px', overflow: 'auto' }); }
                                } else { _elements.box && _elements.box.css({ 'height': 'auto' }); }
                            } else {
                                _class.showEmptyMsg();
                            }
                            _needBuild = false; //dont build agaiin;
                        } else {
                            _class.showEmptyMsg();
                            _needBuild = true; //error , need build agaiin;
                        }
                        var dataTmp = jsonInfo ? jsonInfo.concat(data) : data;
                        if (_options.afterbuild) { (_options.afterbuild).call(im, dataTmp, _elements); }
                    },
                    error: function (e) {
                        _class.showEmptyMsg();
                        if (_options.afterbuild) { (_options.afterbuild).call(im, undefined, _elements); }
                    }
                });
            } else if (_options.cookie && !_options.getUrl) {//from cookie
                var data = $.cookie(_options.cookie);
                if (!data) { return false; }
                data = data.split(_options.separateItem);
                if (_options.order === 'desc') {
                    data = data.reverse();
                }
                var i = 0, l = data.length,
                             cur, tmp = {}, html = [];
                for (; i < l; ++i) {
                    cur = data[i].split(_options.separateData);

                    //store itemNum
                    that._ItemNum.push(cur[0]);

                    tmp = {
                        ItemNum: cur[0],
                        Title: cur[1] || '',
                        Price: cur[2] || '',
                        Qty: cur[3] || '1',
                        Param: cur[4] || ''
                    }
                    if (!_options.liveupdate && (new RegExp(tmp.ItemNum + '$', 'g')).test(location.pathname)) {	//dont update live
                    } else {
                        html.push(_class.getItemHTML(tmp));
                    }
                }
                if (html.length > 0) {
                    _class.hideEmptyMsg();
                    _elements.box && _elements.box.html(html.join(''));
                    if (html.length > 3) {//set box height
                        var box = $(_elements.box),
                                           hideBox = box.add(box.parents()).filter(function (index) {
                                               return $(this).css('display') === 'none';
                                           }),
                                           bh = 0;
                        hideBox.show();
                        box.find('> *').slice(0, 3).each(function () {
                            bh += $(this).outerHeight(true);
                        });
                        hideBox.hide();
                        if (bh > 0) { box.css({ height: bh + 'px', overflow: 'auto' }); }
                    } else { _elements.box && _elements.box.css({ 'height': 'auto' }); }
                } else {
                    _class.showEmptyMsg();
                }
                if (_options.afterbuild) { (_options.afterbuild).call(im, undefined, _elements); }
            }
        },
        showTooltip: function (mode, obj) {
            return $.showTooltip(mode, obj);
        },
        boxLoading: function (tip) {
            tip = tip || "load";
            var tipclass = {
                "error": "load-box-error"
            };
            var tiptxt = {
                "load": "loading",
                "error": "load error!"
            };
            tipclass = tipclass[tip] || 'load-box';
            tiptxt = tiptxt[tip];
            tip = $('<div class="' + tipclass + '">' + tiptxt + '<s></s></div>');
            return tip;
        },
        /** filled && fix data with _options.defaultData */
        fillData: function (data, mode) {
            var def = _handle[mode]['defaultData'] || _options.defaultData || _defData[mode] || _defData['normal']; //依次为：当前handle、当前类、默认handle、默认
            if (def) {
                data.length = def.length;
                var i = 0, l = data.length;
                for (; i < l; ++i) {
                    if (data[i] === undefined || data[i] !== data[i]) {	//undefined or NaN
                        data[i] = (def[i] === '') ? '&nbsp;' : def[i];
                    }
                }
            }
            return data;
        },
        /** format item arguments to json
        * {
        *       key:[k1,k2,...],
        *       key2:[...
        * }
        */
        parseItemData: function (args, mode) {
            args = _SLICE.call(args);
            //if(mode === 'remove') {return args;}
            //var filled = (mode === 'update' && (_handle[mode + 'Url']||_handle[mode]['url']||_handle[mode])) ? false : true;
            var data = {}, key, keyValue;
            var defData = _handle[mode]['defaultData'] || _options.defaultData || _defData[mode] || _defData['normal']; //依次为：当前handle、当前类、默认handle、默认
            if ((typeof (args[0]) === 'string') && defData.length > 1) {	//single item
                //if (filled) {
                args = _class.fillData(args, mode);
                //}
                key = args[0];
                keyValue = args.slice(1);
                data[key] = keyValue;
            } else if ($.isArray(args[0]) && defData.length > 1) {    //multiple
                var i = 0, l = args.length;
                for (; i < l; ++i) {
                    //if (filled) {
                    args[i] = _class.fillData(args[i], mode);
                    //}
                    key = args[i][0];
                    keyValue = args[i].slice(1);
                    data[key] = keyValue;
                }
            } else if (defData.length === 1) {
                var i = 0, l = args.length;
                for (; i < l; ++i) {
                    args[i] = _class.fillData(args[i], mode);
                    key = args[i];
                    keyValue = [];
                    data[key] = keyValue;
                }
            }
            return data;
        },
        showEmptyMsg: function () {
            if (!_elements) { return false; }
            _elements.dialog && _elements.dialog.addClass(_options.classNoitem);
            _elements.box && _elements.box.html(_emptyMsg);
        },
        hideEmptyMsg: function () {
            if (!_elements) { return false; }
            _elements.dialog && _elements.dialog.removeClass(_options.classNoitem);
            _emptyMsg && _emptyMsg.remove();
        }
    };
    var im = /** @lends ItemManager.prototype */{
    /** show dialog */
    'show': function (needBuild) {

        var beforeCallBack = _options.beforeshow,
			  afterCallBack = _options.aftershow;

        beforeCallBack && beforeCallBack.call(im, _elements);

        if (needBuild || (_needBuild && _options.liveupdate)) { _class.initBuild(); }
        if (_elements) {
            _elements.link && (_elements.link).parent().addClass('select');
            _elements.dialog && (_elements.dialog).show();

            //for test
            if (this.HasIframe != true && $.browser.msie && $.browser.version < 7) {
                this.HasIframe = true;
                var nh = $(_elements.dialog).height() + 10;
                //$(_elements.dialog).prepend('<iframe scr="javascript:false;" frameBorder="none" style="width:100%;height:' + nh + 'px;border:none;position:absolute;z-index:-1;"></iframe>');
                var ifr = document.createElement('iframe');
                ifr.src = 'javascript:false;';
                ifr.frameBorder = 'none';
                with (ifr.style) {
                    height = nh + 'px';
                    width = '102%';
                    border = 'none';
                    position = 'absolute';
                    top = '0';
                    left = '0';
                    zIndex = '-1';
                }
                $(_elements.dialog).get(0).appendChild(ifr);
            }

            afterCallBack && afterCallBack.call(im, _elements);
        }
    },
    /** hide dialog */
    'hide': function () {
        if (_elements) {
            _elements.link && (_elements.link).parent().removeClass('select');
            _elements.dialog && (_elements.dialog).hide();
        }
        if (_dialogShow) {
            clearTimeout(_dialogShow);
            _dialogShow = '';
        }
    },
    'get': function () {
    },
    'initDialog': function () {
        _class.initBuild();
    },
    'getItemNum': function () {
        return _class.getItemNum();
    }
};
//auto create handle(default: add,update,remove)
if (_handle) {
    for (var hd in _handle) {
        (function (hd) {
            /** handle
            * @example
            * handle.add("itemNum","qty");	//add single item
            * handle.add(["itemNum1","qty"],["itemNum2","qty"]);	//add multiple items
            */
            im[hd] = function () {
                var data = _class.parseItemData(arguments, hd);
                _class.saveItem(data, hd);
            }
        })(hd);
    }
}
$(function () {
    //初始化
    _class.init();
});
return im;
};
/** @memberOf ItemManager.prototype */
var cart = ItemManager({
    hookID: 'MyCart',
    getUrl: get_siteinfo.root() + 'cart/getcartline',
    handle: {
        'add': get_siteinfo.root() + 'cart/addtocart', //(itemNum,Title,Price,Qty)
        'update': get_siteinfo.root() + 'cart/changelineqty', //(itemNum,Qty)
        'remove': get_siteinfo.root() + 'cart/removeitem', //(itemNum)
        'tosaved': {	//(itemNum,Qty)
            'needLogin': true,
            'url': get_siteinfo.root() + 'cart/movecarttosaveditem',
            'defaultData': ['-', 1]
        },
        towish: {	//(itemNum,Title,Price,Qty)
            'needLogin': true,
            'url': get_siteinfo.root() + 'member/carttowishlist',
            'param': 'wlStr',
            'paramplus': 'issaveditem=false'
        }
    },
    //order: 'desc',
    "param": 'itemString',
    //defaultData: ['-', '-', '-', 1],
    jsonInfo: 0,
    template: '<dl class="cart-item" id="<#=boxID#>"><dd class="pic"><a href="<#=link#>" title="<#=title#>"><img src="<#=pic#>" /></a></dd><dt class="cot"><h4 class="title"><a href="<#=link#>" title="<#=title#>"><#=shorttitle#></a></h4></dt><dd class="data"><span class="qty">Qty:<span id="<#=boxID#>_qty"><#=qty#></span></span> <span class="cost"><span id="<#=boxID#>_price"><#=price#></span></span></dd></dl>',
    emptyMsg: '<p class="tip-noitem">There are NO items in your cart.</p>',
    afteradd: function (data, els) {
        var w = $('#CartSummaryContent'); //cart summary
        //summary dialog
        var win = window;
        if (window.location !== top.location) {//in frame
            win = top;
            setTimeout(function () {
                top.TB_remove();
            }, 700);
            w = $(parent.document.getElementById('CartSummaryContent'));
        }
        if (w.length) {
            setTimeout(function () {
                win.ReLoadCart();
            }, 500);
        } else {
            setTimeout(function () {
                win.cart.show(true);
            }, 500);
        }
        //wish list grid
        if ($('#WishListGrid').length) {
            var wd = data.split('~'),
			  rData = [];

            var i = 0, l = wd.length;
            for (; i < l; ++i) {
                (function (i) {
                    wd[i] = wd[i].split('^');
                    rData.push(wd[i][0])
                })(i);
            }
            var CurrentItemID = data.split("^")[0];
            var wishListItemID = "WishListItem_" + CurrentItemID;
            $("#DialogWishList dl.data-item").each(function () {
                if ($(this).attr("id").toUpperCase() == wishListItemID.toUpperCase()) {
                    (wishList.remove).apply('', rData);
                }
            });

        }
        //execute tuples
        if (get_siteinfo.enableCustomCode() === 'true') {
            ES.callbackTuple.execute('AddToCart', data);
        }
    },
    afterupdate: function () {
        var w = $('#CartSummaryContent');
        if (w.length) {
            setTimeout(function () {
                ReLoadSummary();
                ReLoadCartSummary();
            }, 500);
        }
    },
    afterbuild: function (data, els) {
        var count = '0 item';
        if (data) {
            var demo = data[0].split('~');
            //set totalPrice
            var totalPrice = (demo[1] * 1).toFixed(2);
            if (totalPrice !== undefined) { $('#CartTotalPrice').text('$' + totalPrice); }
            //set count
            var cot = demo[0] * 1;
            count = cot > 1 ? cot + ' items' : cot + ' item';
        }
        $('#CartCount').text(count);
        if (cfg.CurrRate() !== "-1") {
            $(".change-price").text($("#CartTotalPrice").text());
            CurrencyRateChange("change-price");   // change currency
        } else {
            $(".currency-change").hide();
        }
    },
    afterremove: function (str, els) {
        var listWrap = $('#CsProductList');
        if (listWrap.length) {
            setTimeout(function () { ReLoadCart(); }, 500);
        }
    },
    aftertosaved: function () {
        if ($('#CartSummaryContent').length && $('#CartContentSiList').length) {
            setTimeout(function () { ReLoadCart(); ReLoadSavedItem(); }, 500);
        }
    },
    aftertowish: function (itemStr) {
        item_info('wl', (new Date).getTime());
        wishList.initDialog();
        var d = itemStr.split('~');
        var i = 0, l = d.length;
        for (; i < l; ++i) {
            d[i] = d[i].split('^');
        }
        (cart.remove).apply('', d);

        //execute tuples        
        if (get_siteinfo.enableCustomCode() === 'true') {
            ES.callbackTuple.execute('AddToWishList', itemStr);
        }
    }
});
/** @memberOf ItemManager.prototype*/
var savedItem = ItemManager({
    needLogin: true,
    defaultData: ['-', 1],
    "param": "itemString",
    handle: {
        'update': get_siteinfo.root() + 'cart/changesaveditemqty',
        'remove': {
            url: get_siteinfo.root() + 'cart/removesaveditem',
            defaultData: ['-']
        },
        'tocart': get_siteinfo.root() + 'cart/movesaveditemtocart',
        'towish': {
            url: get_siteinfo.root() + 'member/carttowishlist',
            'param': 'wlStr',
            'paramplus': 'issaveditem=true',
            defaultData: ['-', '-', '-', 1]
        }
    },
    afteradd: function () {
        setTimeout(function () { ReLoadCart(); ReLoadSavedItem(); }, 500);
    },
    afterupdate: function () {
        setTimeout(ReLoadSavedItem, 500);
    },
    afterremove: function () {
        setTimeout(ReLoadSavedItem, 500);
    },
    aftertocart: function () {
        if ($('#CartSummaryContent').length && $('#CartContentSiList').length) {
            setTimeout(function () { ReLoadCart(); ReLoadSavedItem(); }, 500);
        }
    },
    aftertowish: function (itemStr) {
        item_info('wl', (new Date).getTime());
        wishList.initDialog();
        var d = itemStr.split('~');
        var i = 0, l = d.length;
        for (; i < l; ++i) {
            d[i] = d[i].split('^');
        }
        (savedItem.remove).apply('', d);
    }
});
var outofStock = ItemManager({
    defaultData: ['-'],
    "param": "itemNum",
    handle: {
        'remove': {
            url: get_siteinfo.root() + 'cart/removeoutstockitem',
            defaultData: ['-']
        }
    },
    afterremove: function () {
        var listWrap = $('#J_OutStockContainer');
        if (listWrap.length) {
            setTimeout(function () { ReLoadCart(); }, 500);
        }
    }
});
/** @memberOf ItemManager.prototype */
var wishList = ItemManager({
    hookID: 'WishList',
    needLogin: true,
    getUrl: get_siteinfo.root() + 'member/wishlistsummary',
    handle: {
        'add': get_siteinfo.root() + 'member/addwishlist',
        'update': get_siteinfo.root() + 'member/updatewishlist',
        'remove': get_siteinfo.root() + 'member/delwishlist'
    },
    "param": "wlstr",
    //order: 'desc',
    template: '<dl class="data-item" id="<#=boxID#>"><dd class="pic"><a href="<#=link#>" title="<#=title#>"><img src="<#=pic#>" title="<#=title#>"></a></dd><dt><a href="<#=link#>" title="<#=title#>"><#=shorttitle#></a></dt><dd class="handle"><span class="cost curr-change-wish"><#=price#></span><span class="addlist addlist-<#=idfix#>"><a id="J_WLLink_<#=idfix#>" class="tip-loading link-handle-cart" href="###"><span>Loading</span></a></span></dd></dl>',
    emptyMsg: '<p class="tip-noitem">There are NO items in your wish list.</p>',
    afteradd: function (da) {
        var win = window;
        if (window.location !== top.location) {
            win = parent;
            setTimeout(function () {
                parent.TB_remove();
            }, 700);
        }
        setTimeout(function () {
            win.wishList.show(true);
        }, 500);
        //execute tuples
        if (get_siteinfo.enableCustomCode() === 'true') {
            ES.callbackTuple.execute('AddToWishList', da);
        }
    },
    afterupdate: function (itemStr, els) {
        if ($('#WishListGrid').length) {
            var d = itemStr.split('~');
            var i = 0, l = d.length;
            for (; i < l; ++i) {
                (function (i) {
                    var price, qty, totalprice, sn,
						tpriceEle, symbol;

                    d[i] = d[i].split('^');
                    sn = d[i][0];
                    qty = d[i][1] * 1;

                    price = $.trim($('#' + 'WishItem_' + sn).find('[name=Prs]').text()).replace(/[^\d]*(\d+\.\d+)[^\d\.]*/g, '$1') * 1;
                    if (!$.isNumber(price)) { return false; }
                    totalprice = (qty * price).toFixed(2);
                    tpriceEle = $('#' + 'WishItem_' + sn).find('[name=TtlPrs]');
                    symbol = $.trim(tpriceEle.text()).replace(/(\W)\s*(?:\d+\.\d+)/g, '$1');
                    tpriceEle.text(symbol + '' + totalprice);
                })(i);
            }
        }
    },
    afterremove: function (els) {
        var listWrap = $('#WLNoEmptyM');
        if (listWrap.length) {
            var pas = location.search;
            if (pas !== '') {
                location.search = $.urlParam(pas, 'page', '');
            } else {
                location.reload();
            }
        }
    },
    //after build HTML, query item qty JSON for show handle button
    afterbuild: function (da, eles) {
        if (!da || da.length === 0) { return false; }
        var callee = arguments.callee;
        //check qty
        //qty check
        var nums = this.getItemNum() || [];

        ES.checkCartHandle.init({
            imgSelector: '#DialogWishList a.link-handle-cart',
            imgIdFix: 'J_WLLink_',
            itemNums: nums.join('^'),
            afterbuild: function (el, qty, itemNum, status) {
                //                if (status * 1 <= 0) {
                //                    $('#WishListItem_' + itemNum).remove();
                //                    return false;
                //                }               
                var sel = '#J_WLLink_' + itemNum;
                el = $(sel);
                el.attr('data-qty', qty).attr('data-itemNum', itemNum);
                if (qty > 0 && status == 1) {
                    el.removeClass('tip-loading').addClass('link-red').html('<span>Add To Cart</span>');
                } else {
                    el.removeClass('tip-loading').addClass('link-blue').html('<span>Notify Me</span>')
                }
                CurrencyRateChange("curr-change-wish");
                if ($(".dialog-item-wish .data-item").length > 3) {
                    $("#DialogWishList .data-item .handle .addlist").css("float", "left"); //改变对齐方式
                }
            },
            addToCart: function (itemNum) {
                cart.add(itemNum);
            },
            notify: function (itemNum) {
                autoNotify && autoNotify(itemNum);
            }
        });
    }
});
/** @memberOf ItemManager.prototype */
var recently = ItemManager({
    cookie: 'rv',
    hookID: 'RecentlyViewed',
    defaultData: ['-', '-', '-', '1', '', ''],
    template: '<dl class="data-item" id="<#=boxID#>"><dd class="pic"><a href="<#=link#>" title="<#=title#>"><img src="<#=pic#>" title="<#=title#>"></a></dd><dt><a href="<#=link#>" title="<#=title#>"><#=shorttitle#></a></dt><dd class="handle"><span class="cost curr-change-rv"><#=price#></span><input type="hidden" name="InstockQty" id="InstockQty_<#=boxID#>" value="<#=qty#>" /><span class="addlist addlist-<#=idfix#>"><a id="J_RVLink_<#=idfix#>" class="tip-loading link-handle-cart" href="###"><span>Loading</span></a></span></dd></dl>',
    emptyMsg: '<p class="tip-noitem">There are NO items in your recently viewed list.</p>',
    order: 'desc',
    liveupdate: false,
    afterSaveCookie: function (allcookie, el) {
        //仅显示最近的5个
        var ncookie = allcookie.split('~'),
			maxNum = 5;
        if (ncookie.length >= maxNum) {
            ncookie.splice(0, ncookie.length - maxNum);
            $.cookie('rv', ncookie.join('~'));
        }
    },
    afterbuild: function (data, els) {
        //qty check
        var nums = this.getItemNum() || [];

        ES.checkCartHandle.init({
            imgSelector: '#DialogRecentlyViewed a.link-handle-cart',
            imgIdFix: 'J_RVLink_',
            itemNums: nums.join('^'),
            afterbuild: function (el, qty, itemNum, status) {
                if (status * 1 <= 0) {
                    $('#RecentlyViewedItem_' + itemNum).remove();
                    return false;
                }
                el = $(el);

                if (qty > 0 && status == 1) {
                    el.removeClass('tip-loading').addClass('link-red').html('<span>Add To Cart</span>');
                } else {
                    el.removeClass('tip-loading').addClass('link-blue').html('<span>Notify Me</span>')
                }
                CurrencyRateChange("curr-change-rv");
                if ($(".dialog-item-rv .data-item").length > 3) {
                    $(".dialog-item-rv .data-item .handle .addlist").css("float", "left"); //改变对齐方式
                }
            },
            addToCart: function (itemNum) {
                cart.add(itemNum);
            }
        });
    }
});

/** @memberOf ItemManager.prototype */
$(function () {
    var $DialogGetEx = $("#DialogGetExclusive");
    $AGetEx = $("#GetExclusive");
    $LiGetEx = $(".get-exclusive");

    $DialogGetEx.insertAfter("#GetExclusive");
    $AGetEx.click(function (event) {
        event.preventDefault();
        $DialogGetEx.css("display", "block");
        $LiGetEx.addClass("select");
    });
    $("#DialogGetExclusive .dialog-close").click(function () {
        $DialogGetEx.css("display", "none");
        $LiGetEx.removeClass("select");
    });
    $DialogGetEx.parent().mouseleave(function () {
        if (focus_status_GetEx !== true) {
            $DialogGetEx.css("display", "none");
            $LiGetEx.removeClass("select");
        }
    });
});

/*-- public END --*/
/** search key function */
function searchKey() {
    //save key
    var url = location.href,
            srhPage = 'search/',
            paramKey = 'q';
    if (url.indexOf(srhPage) !== -1 && !$('div.page-404').length) {  //only run on search page
        var key, value;
        key = $.urlParam(url, paramKey);
        value = url.split(srhPage)[1];
        if (key && value) {// add by alex 20100430
            recently_search(encodeURIComponent(key), encodeURIComponent(value));
            //set search input value
            $('#SBarTxt').val(decodeURIComponent(key));
        }
    }
    //build key
    var box = $('#RecentSearchList');
    if (box.length) {
        var wrap = box.parents('div.recent-search'),
                  data = recently_search(),
                  html = '';
        wrap.hide();
        if (!data) { return false; }
        wrap.show();
        for (var it in data) {
            html = '<li><a href="' + get_siteinfo.root() + srhPage + decodeURIComponent(data[it]) + '">' + unescape(decodeURIComponent(it).replace(/\\u/g, '%u')) + '</a></li>' + html;
        }
        box.html(html);
    }
}
/** Auto Notify mail
* @param itemNum
*/
function autoNotify(itemNum) {
    var thisObj = $.getEventTarget($.getEvent(autoNotify));
    var box = $('<div class="notify-dialog">' +
                        '<h3 class="title-notify">Auto Notification <span class="dialog-close" onclick="TB_remove()">close</span></h3>' +
                        '<div class="entry">' +
                        '<p class="tip">Please enter your email address below. You will receive an email notification once this item becomes available for purchase.</p>' +
                        '<div class="form-email">' +
                        '<form action="/item/notifyme" method="post"><input id="ItemNum" name="ItemNum" type="hidden" value="' + itemNum + '">' +
                        '<label>Email Address:</label><input class="input-text" name="AutoNotificationEmail" type="text" value=""> <input type="submit" class="btn-submit" name="ANSumbit" value=" ">' +
                        '<div class="notifyMsg"><span></span></div>' +
                        '</form>' +
                        '</div>' +
                        '<p class="tip-note"><strong>Note:</strong> Due to limited supply, all stock is sold on a first-come first-serve basis. Auto Notification does not guarantee availability or price. <br>All prices are subject to change without notice. </p>' +
				'</div>' +
				'<div class="notify-success"><div class="dialog-icon icon-success"></div>Thank you for submitting your email address. You will receive an email notification once this item becomes available for purchase.</div>' +
                        '</div>');

    //execute tuples
    if (get_siteinfo.enableCustomCode() === 'true') {
        ES.callbackTuple.execute('Impression', 'Auto_Notification', '');
        box.find('.dialog-close').click(function () {
            ES.callbackTuple.execute('Close', get_siteinfo.pagetype(), 'AutoNotify');
        });
    }
    box.find('form').validate({
        rules: {
            AutoNotificationEmail: {
                required: true,
                email: true
            }
        },
        errorLabelContainer: box.find('div.notifyMsg span'),
        highlight: function (element, errorClass) { $(element).addClass(errorClass); },
        unhighlight: function (element, errorClass) { $(element).removeClass(errorClass); },
        messages: {
            AutoNotificationEmail: {
                required: "Please enter a valid email address.",
                email: "Please enter a valid email address."
            }
        },
        submitHandler: function (f) {
            var data = $(f).serialize();
            var url = $(f).attr("action");
            $.ajax({
                type: "POST",
                url: url,
                dataType: "JSON",
                data: data,
                success: function (d) {
                    if (d === "true") {
                        $('#TB_ajaxContent>.notify-dialog>.entry').hide().next('.notify-success').show().append('<p style="line-height:30px;text-indent:-50px;font-weight:normal;font-size:11px;text-align:center;">This dialog will close in <span id="J_NotifyTimeBar">3</span> seconds.</p>');
                        var intv = setInterval(function () {
                            var n = $('#J_NotifyTimeBar').text() * 1 - 1;
                            $('#J_NotifyTimeBar').text(n);
                            if (n < 1) {
                                clearInterval(intv);
                                TB_remove();
                            }
                        }, 1000);
                    }
                    if (get_siteinfo.enableCustomCode() === 'true') {
                        ES.callbackTuple.execute('AutoNotification', get_siteinfo.pagetype(), itemNum);
                    }
                },
                error: function (msg) { alert(msg) }
            });
            return false;
        }
    });
    var tmpWrap = $('<div id="autoNotifyWrapTemp"></div>');
    tmpWrap.hide().append(box).appendTo($('body'));
    TB_show('', '#TB_inline?height=171&width=518&modal=true&inlineId=autoNotifyWrapTemp');
    tmpWrap.remove();
}
/**** page load Function ****/
$(function () {
    searchKey(); //save & show Recently Search Key & set search input value

    //init ui config (cookie)
    (function () {
        var uiconfig = new UIConfig();
        uiconfig._Save();
    })();

    (function () {//Navigate Main
        var nav = $('#NavMain');
        if (nav.length) {
            var navLinks = nav.find('a'),
                  navBox = [],
                  regx = /\d+$/g;
            $('#NavSonWrap').insertAfter(nav);
            navLinks.each(function () {
                var hf = $(this).text().replace(/\W/g, ''); //use menu text
                hf = '#NavMain_' + hf;
                if ($(hf).length) {
                    this.NAVBOX = $(hf) || '';
                    this.NAVBOX.get(0).NAVLINK = this;
                    navBox.push(this.NAVBOX.get(0));
                    if ($.browser.msie && $.browser.version < 7) {
                        var nh = $(this.NAVBOX).height();
                        //$(this.NAVBOX).prepend('<iframe scr="javascript:false;" frameBorder="none" style="width:100%;height:' + nh + 'px;border:none;position:absolute;z-index:-1;"></iframe>');
                        var ifr = document.createElement('iframe');
                        ifr.src = 'javascript:false;';
                        ifr.frameBorder = 'none';
                        with (ifr.style) {
                            height = nh + 'px';
                            width = '100%';
                            border = 'none';
                            position = 'absolute';
                            top = '0';
                            left = '0';
                            zIndex = '-1';
                        }
                        $(this.NAVBOX).get(0).appendChild(ifr);
                    }
                }
            });
            var allEles = $.merge(navLinks, navBox);
            $(allEles).hover(function () {
                var el = this;
                if (el.NAVLINK) { clearTimeout(nav.get(0).HideNavCate); }
                nav.get(0).ShowNavCate = setTimeout(function () {
                    $(el.NAVLINK || el).addClass('select');
                    $(el.NAVBOX || el).show();
                }, 300);
            }, function () {
                var el = this;
                clearTimeout(nav.get(0).ShowNavCate);
                nav.get(0).HideNavCate = setTimeout(function () {
                    $(el.NAVLINK || el).removeClass('select');
                    $(el.NAVBOX || el).hide();
                }, 150);
            });
        }
    })();

    //MyAccount dialog show
    $('#MyAccount').each(function () {
        var tarEle = '#' + ($(this).attr('href').split('#')[1]),
                ele = this;
        var d_show = function () { $(ele).parent().addClass('select'); $(tarEle).show(); },
                d_hide = function () { $(ele).parent().removeClass('select'); $(tarEle).hide(); }
        $(this).click(function (e) {
            if (e) { e.preventDefault(); }
            d_show();
            this.blur();
            if (this.HasIframe != true && $.browser.msie && $.browser.version < 7) {
                this.HasIframe = true;
                var nh = $(tarEle).height() - 7;
                //$(tarEle).prepend('<iframe scr="javascript:false;" frameBorder="none" style="width:100%;height:' + nh + 'px;border:none;position:absolute;z-index:-1;"></iframe>');
                var ifr = document.createElement('iframe');
                ifr.src = 'javascript:false;';
                ifr.frameBorder = 'none';
                with (ifr.style) {
                    height = nh + 'px';
                    width = '100%';
                    border = 'none';
                    position = 'absolute';
                    top = '0';
                    left = '0';
                    zIndex = '-1';
                }
                $(tarEle).get(0).appendChild(ifr);
            }
        })
        .hover(function (e) {
            clearTimeout(ele.ShowDialogFunc);
        }, function (e) {
            ele.ShowDialogFunc = setTimeout(d_hide, 100);
        });
        $(tarEle).hover(function (e) {
            clearTimeout(ele.ShowDialogFunc);
        }, function (e) {
            if (!focus_status) {
                ele.ShowDialogFunc = setTimeout(d_hide, 100);
            };
        });
        $(tarEle).find('.dialog-close').click(d_hide);
    });

    //search
    if ($("#SBarTxt").length) {
        $.use('plugin.combo', function () {
            $("#SBarTxt").keypress(function (e) {
                if (e.keyCode === 13) {
                    $("#SBarGo").click();
                }
            }).jSuggest({
                url: get_siteinfo.sug() + "sug",
                type: "POST",
                data: "s",
                autoChange: true
            });
            $("#SBarGo").click(function () {
                var navCatId = $("#SBarNavCat").val();
                var queryText = $("#SBarTxt").val();
                if (queryText == "") {
                    $.dialog("Please enter a search term and try again.");
                } else {
                    queryText = RemoveDuplicateKeyword(queryText);

                    if (get_siteinfo.enableCustomCode() === 'true') {
                        ES.callbackTuple.execute('TextSearch');
                    }

                    window.location.href = get_siteinfo.root('http:') + "search/" + navCatId + "?q=" + queryText;
                }
            });
        });
    }

    //get Exclusive box
    if ($("#Subscription_btn0").length) {
        $('input[name="SubscribeEmail0"]').change(function () {
            if ($.isEmailAddress($(this).val())) {
                $(this).css('border', '1px solid #CCCCCC');
                $('#errorOffers0').text('');
            }
            else {
                $(this).css("border", "1px solid #b01105");
                $("#errorOffers0").text('Please enter your email address.').css('color', 'red');
            }
            return false;
        });
        $('#Subscription_btn0').click(function (e) {
            var email0 = $('input[name="SubscribeEmail0"]');
            if (email0 && $.isEmailAddress($(email0).val())) {
                window.location.href = get_siteinfo.root() + 'subscribenews?subscriber.EmailAddress=' + $(email0).val() + '&reply=' + document.location.href;
            }
            else {
                $(email0).css("border", "1px solid #b01105");
                $("#errorOffers0").text('Please enter your email address.').css('color', 'red');
            }
            return false;
        });
    }

    //news letter
    if ($("#Subscription_btn").length) {
        $('input[name="SubscribeEmail"]').change(function () {
            if ($.isEmailAddress($(this).val())) {
                $(this).css('border', '1px solid #CCCCCC');
                $('#errorOffers').text('');
            }
            else {
                $(this).css("border", "1px solid #b01105");
                $("#errorOffers").text('Please enter your email address.').css('color', 'red');
            }
            return false;
        });
        $('#Subscription_btn').click(function (e) {
            var email = $('input[name="SubscribeEmail"]');
            if (email && $.isEmailAddress($(email).val())) {
                window.location.href = get_siteinfo.root() + 'subscribenews?subscriber.EmailAddress=' + $(email).val() + '&reply=' + document.location.href;
            }
            else {
                $(email).css("border", "1px solid #b01105");
                $("#errorOffers").text('Please enter your email address.').css('color', 'red');
            }
            return false;
        });
        //        $.use('plugin.combo', function () {
        //            $("#SubscribeNewsForm").validate({
        //                rules: {
        //                    SubscribeEmail: {
        //                        required: true,
        //                        email: true
        //                    }
        //                },
        //                messages: {
        //                    SubscribeEmail: { required: 'Please enter your email address.' }
        //                },
        //                errorLabelContainer: "#errorOffers",
        //                highlight: function (element, errorClass) { $(element).css("border", "1px solid #b01105") },
        //                unhighlight: function (element, errorClass) { $(element).css("border", "1px solid #c4c4c4") },
        //                submitHandler: function (form) {
        //                    window.location.href = $(form).attr("action") + "?subscriber_EmailAddress=" + $(form).find("input[name='SubscribeEmail']").text() + "&reply=" + document.location.href;
        //                    //                    $.ajax({
        //                    //                        url: $(form).attr("action"),
        //                    //                        data: $(form).serialize(),
        //                    //                        cache: false,
        //                    //                        type: 'GET',
        //                    //                        success: function (state) {
        //                    //                            var msg = {
        //                    //                                '1': ['Thanks for subscription!', 'success'],
        //                    //                                '2': ['Your Email has already subscribed before!', 'alert'],
        //                    //                                '-1': ['Subscribe failed!', 'warn']
        //                    //                            };
        //                    //                            $.dialog.apply(null, msg[state + ''] || msg['-1']);
        //                    //                        }
        //                    //                  });
        //                }
        //            });
        //        });


        //vote
        var voteContent;
        function submitclick(isVote) {
            if (isVote) {
                if ($("#vote :input[checked='true']").length == 0) {
                    $.dialog('None is Choosed');
                    return;
                }
            }
            var subjectId = $("#vote :input[type='hidden']").val();
            var questionId = $("#vote :input[checked='true']").attr("name");
            var optionsId = $("#vote :input[checked='true']").val();
            var viewUrl = get_siteinfo.vote().replace(/\/$/g, '') + '/view.aspx?sid=' + subjectId + "&" + questionId + "=" + optionsId;
            $.getScript(viewUrl);
        }
        function ShowVoteResults(content) {
            $("#Question_content").empty();
            $("#Question_content").append(content);
        }
        function ShowVote(content) {
            $("#Question_content").empty();
            $("#Question_content").append(content);
            voteContent = content;
        }
        function VoteGoBack() {
            $("#Question_content").empty();
            $("#Question_content").append(voteContent);
            $("#submit").click(function () { submitclick(true) });
            //$("#Question_T img").attr("src", $("#Question_T  img").attr("src").replace("SeePollResults.gif", "PleaseTellUs.gif"));
        }
        window.ShowVote = ShowVote;
        window.submitclick = submitclick;
        window.VoteGoBack = VoteGoBack;
        window.ShowVoteResults = ShowVoteResults;
        window.voteContent = voteContent;
        $('#Question_content').append('<div class="load-page">Loading...<s></s></div>');
        $.getScript(get_siteinfo.vote().replace(/\/$/g, '') + "/vote.aspx", function () { $("#vote #submit").click(function () { submitclick(true) }); });
    }

    //item index page Share Links
    $('#J_BoxSharelink').click(ES.ShareLink.init);
});



/** track类
* @param
*/
ES.trackpage = (function () {
    var GOALS = {}, //The point which we care. Current we have : CategoryGuide/QuickFinder/TextFinder/TextSearch/TextRefineSearch
		ACTIONS = {}; //the action about the focus, AddtoCart/QuickInfo/NotifyMe/ or other click action
    /*--
    var datalist = {
    FCS: '', //The point which we care. Current we have : CategoryGuide/QuickFinder/TextFinder/TextSearch/TextRefineSearch
    PAG: '', //Index/Category/ProductType/Brand/Model/Item/Cart/Checkout/Billing/OrderReview/PaypalReview/Confirm/Others Page …
    ACT: '', //the action about the focus, AddtoCart/QuickInfo/NotifyMe/ or other click action
    CAT: '', //category name
    PRD: '', //Producttype name
    SBP: '', //Sub producttype name
    BRN:  '', //BrandName
    SRS: '', //Series name,
    MDL: '', //model name
    KWD: '', //search keyword
    ITM:''	//itemNum
    };
    --*/

    var Tracker = {
        /** add goals
        * @param {String} name Goal Name
        * @param {Object} settings goal setting. (you can set: getData())
        */
        addGoal: function (name, settings) {
            if (typeof (name) !== 'string') {
                for (var i in name) {
                    arguments.callee.call(this, i, name[i]);
                }
            } else {
                GOALS[name] = settings;
            }
        },
        /** add actions
        * @param {String} name Action Name
        * @param {Object} settings
        */
        addAction: function (name, settings) {
            if (typeof (name) !== 'string') {
                for (var i in name) {
                    arguments.callee.call(this, i, name[i]);
                }
            } else {
                ACTIONS[name] = settings;
            }
        },
        /** tracking
        * @param {String} goalName Goal Name
        * @param {String} pageType page type
        * @description 除去goalName和pageType两个参数，其余参数都会传递给当前goal的getData()进行处理
        */
        tracking: function (goalName, pageType) {
            this._execute.apply(this, ['goal'].concat([].slice.call(arguments)));
        },
        doAction: function (actionName, pageType) {
            this._execute.apply(this, ['action'].concat([].slice.call(arguments)));
        },
        _execute: function (type, name, pageType) {
            var data,
				pns = [], pvs = [];
            //get data
            data = this._getData.apply(this, arguments) || {};

            //format data
            for (var i in data) {
                if (data[i] && data[i] != '') {
                    pns.push(i);
                    pvs.push(encodeURIComponent(data[i]));
                }
            }

            //test alert info
            /*--
            var s = $.JSONtostring(data);
            s = s.replace(/([\,\{\}])/igm,'\n');
            alert(type + ' '+name+' data:\n'+s);
            --*/

            if (window.scentfunction2) {
                var backFunc = document.write;
                document.write = function (html) { $('<span style="position:absolute;"></span>').html(html).appendTo(document.body); }
                scentfunction2(pageType, '02', pns, pvs);
                document.write = backFunc;
            }
        },
        _getSID: function (goal) {
            //addtocart means one shopping session end.
            var key = 'sid', sid;
            sid = $.createGUID(key, false);
            if (goal === 'AddToCart') {
                $.createGUID(key, true);
            }
            return sid;
        },
        _getFID: function (goal, recreate) {
            var key = 'fid', needReCreate = false, fid;
            if (goal === 'AddToCart') {
                fid = $.createGUID(key, false);
                $.createGUID(key, true);
            }
            else {
                if (recreate === true) {
                    needReCreate = true;
                }
                fid = $.createGUID(key, needReCreate);
            }
            return fid;
        },
        _getData: function (type, name, pageType) {
            type = type.toLowerCase();
            var args = [].slice.call(arguments),
				getChar = '_get' + type,
				goal = this[getChar](name),
				data = {},
				needcreate = (type === 'goal' ? true : false),
				fid = this._getFID(name, needcreate),
                sid = this._getSID(name);

            if (!goal) { throw new Error('No ' + type + ' Named "' + name + '"'); }
            if (goal && goal.keepingwith) {
                goal = this[getChar](goal.keepingwith);
            }
            if (!goal.getData) { throw new Error(type + ' "' + name + '" has no method getData.'); }
            if (goal) {
                data = goal.getData.apply(this, args.splice(3, args.length - 3)) || {};
                data.FID = fid;
                data.SID = sid;
                data.PAG = pageType;
                if (type === 'action') {
                    data.ACT = name;
                } else if (type === 'goal') {
                    data.FCS = name;
                }
            }
            return data;
        },
        _getgoal: function (name) {
            return GOALS[name];
        },
        _getaction: function (name) {
            return ACTIONS[name];
        }
    };

    var GTK;
    return {
        addGoal: function () {
            var gtk = GTK || ES.clone(Tracker);
            gtk.addGoal.apply(gtk, arguments);
        },
        addAction: function () {
            var gtk = GTK || ES.clone(Tracker);
            gtk.addAction.apply(gtk, arguments);
        },
        tracking: function () {
            var tk = ES.clone(Tracker);
            tk.tracking.apply(tk, arguments);
        },
        doAction: function () {
            var tk = ES.clone(Tracker);
            tk.doAction.apply(tk, arguments);
        }
    };
})();
ES.trackpage.addGoal({
    NavigationBrowsing: {
        getData: function (category) {
            var da = {
                CAT: category || ''
            };
            return da;
        }
    },
    Finder: {
        getData: function (cate, brand, series, model, proType, subProType) {
            var da = {
                CAT: cate || '', //category name
                PRD: proType || '', //Producttype name
                SBP: subProType || '', //Sub producttype name
                BRN: brand || '', //BrandName
                SRS: series || '', //Series name,
                MDL: model || '' //model name
            };
            return da;
        }
    },
    TextFinder: { keepingwith: 'Finder' },
    TextSearch: {
        getData: function (keyword, cate) {
            var da = {
                KWD: keyword,
                CAT: cate
            };
            return da;
        }
    },
    TextRefineSearch: { keepingwith: 'TextSearch' }
});
ES.trackpage.addAction({
    AddToCart: {
        getData: function (itemNum) {
            var da = {
                ITM: itemNum || ''
            };
            return da;
        }
    },
    AddToWishList: { keepingwith: 'AddToCart' },
    NotifyMe: { keepingwith: 'AddToCart' }
});

/*-- tracking code --*/
(function () {
    $.createGUID('sid', false);
    ES.callbackTuple.add('HomeFinder', function () {
        bannerTracking('/bannerads/finder/' + get_siteinfo.pagetype().toLowerCase() + 'page/finder_btn');

        var cate = $('#qfCategories'),
            brand = $('#qfBrands'),
			model = $('#qfModels'),
			series = $('#qfSeries'),
			protype = $('#qfProducttypes'),
			protype2 = $('#qfProducttypes2'),
			subProtype = $('#qfSubProducttypes'),
			isByBrand = ($('#J_QuickFinderForm').find('.byType').css('display') === 'none') ? true : false;
        var ca = cate.children('option:selected').val(),
			bi = brand.children('option:selected').val(),
			si = series.children('option:selected').val(),
			mi = model.children('option:selected').val(),
            pi = isByBrand ? protype.children('option:selected').val() : protype2.children('option:selected').val(),
	    	spi = subProtype.children('option:selected').val();
        ES.trackpage.tracking('Finder', get_siteinfo.pagetype(), ca, bi, si, mi, pi, spi);
    });
    ES.callbackTuple.add('TextSearch', function () {
        bannerTracking('/bannerads/search/text_search_btn');
        var keyword = $('#SBarTxt').val(),
			cate = $('#SBarNavCat').children('option:selected').val();
        ES.trackpage.tracking('TextSearch', get_siteinfo.pagetype(), keyword, cate);
    });
    ES.callbackTuple.add('TextRefineSearch', function () {
        bannerTracking('/bannerads/search/refine_text_search_btn');

        var keyword = $('#RefineSrhText').val(),
			cate = GetParama().split('##')[0];
        ES.trackpage.tracking('TextRefineSearch', get_siteinfo.pagetype(), keyword, cate);
    });
    ES.callbackTuple.add('CategoryFinder', function () {
        var page = get_siteinfo.pagetype() + "page";
        var navpath = $('#Body .nav-path').find('*');
        if(page.toLowerCase() == 'categorypage' && navpath != undefined && navpath.length > 2)
        {
           page = page + "/" + navpath.eq(1).text().replace(/\W/g, '').replace(/Accessories/gim, '');
        }
        bannerTracking('/bannerads/finder/' + page.toLowerCase() + '/finder_btn');

        var cate = GetParama().split('##')[0],
			brand = $('#qfBrandSel').children('option:selected').val(),
			model = $('#qfModelSel').children('option:selected').val(),
			series = $('#qfSeriesSel').children('option:selected').val(),
			protype = $('#qfProductTypeSel').children('option:selected').val(),
			subProtype = $('#qfSubProductTypeSel').children('option:selected').val();

        ES.trackpage.tracking('Finder', get_siteinfo.pagetype(), cate, brand, series, model, protype, subProtype);
    });
    ES.callbackTuple.add('TextFinder', function () {
        bannerTracking('/bannerads/finder/' + get_siteinfo.pagetype().toLowerCase() + 'page/text_finder_btn');

        var params = GetParama().split('##');
        var cate = params[0],
			brand = params[1],
			model = params[2],
			series = '',
			protype = '',
			subProtype = '';

        ES.trackpage.tracking('TextFinder', get_siteinfo.pagetype(), cate, brand, series, model, protype, subProtype);
    });

    ES.callbackTuple.add({
        'AddToCart': function (dataStr) {
            var data = dataStr.split('~'),
				itemNums = [];
            var i = 0, l = data.length;
            for (; i < l; ++i) {
                itemNums.push(data[i].split('^')[0]);
            }
            itemNums = itemNums.join('~');
            ES.trackpage.doAction('AddToCart', get_siteinfo.pagetype(), itemNums);
        },
        'AddToWishList': function (dataStr) {
            var data = dataStr.split('~'),
				itemNums = [];
            var i = 0, l = data.length;
            for (; i < l; ++i) {
                itemNums.push(data[i].split('^')[0]);
            }
            itemNums = itemNums.join('~');
            ES.trackpage.doAction('AddToWishList', get_siteinfo.pagetype(), itemNums);
            //ES.trackpage.doAction('AddToCart',get_siteinfo.pagetype(),itemNums);
        },
        'NotifyMe': function (itemnum) {
            ES.trackpage.doAction('NotifyMe', get_siteinfo.pagetype(), itemnum);
        }
    });
})();

//change currency rate
function CurrencyRateChange(priceClass) {
    var cfg = new UIConfig();
    if (cfg.CurrRate() !== "-1") {
        if ($("." + priceClass).length !== 0) {
            $("." + priceClass).each(function () {
                if ($(this).text().replace(/\s/gi, "").substring(0, 1) == "$") {
                    var CurrPrice = parseFloat($(this).text().replace(/\s/gi, "").substring(1)) * parseFloat(cfg.CurrRate());
                    $(this).text(cfg.Currency() + " " + CurrPrice.toFixed(2));
                }
            });
        }
        if ($(".inter-remark").length !== 0) {
            $(".inter-remark").show();  // show international ship remark 
        }
    }
}

// change currency rate  for CatePriceRange
function NarrowPriceChangeCurr() {
    var cfg = new UIConfig();
    if (cfg.CurrRate() !== "-1") {
        $("#CatePriceRange a[rev]").each(function () {
            var arr = $(this).text().split(" ");
            $.each(arr, function (i, k) {
                if (k.substring(0, 1) == "$") {
                    var CurrPrice = parseFloat(k.replace(/\s/gi, "").substring(1)) * parseFloat(cfg.CurrRate());
                    arr[i] = cfg.Currency() + " " + CurrPrice.toFixed(2);
                }
            });
            var thisText = arr.join(" ");
            $(this).html("<s></s>" + thisText);
        });
    }
}

// styleNum "0" For big img    "1" For small img
function AddToCartStyleChange(addToCartClass, styleNum) {
    var cfg = new UIConfig();
    if (cfg.CurrRate() !== "-1") {
        $("." + addToCartClass).html("<span class='disable-addCart" + styleNum + "'>Add To Cart</span>");
    }
}

// if Is show "This item is not available for international shipments"
function IsShowWarnInfo(WarnInfoClass) {
    var cfg = new UIConfig();
    if (cfg.CurrRate() !== "-1") {
        $("." + WarnInfoClass).show();
    }
}
// if Is show "This item is not available for international shipments"
function IsShowInfoPromotion(ItemNum) {
    if ($(".warninfo-" + ItemNum).css("display") !== "none") {
        $(".info-promotion-" + ItemNum).hide();
    }
}

//  ES1.Master Ajax Error
function CurrRateError(msg) {
    alert(msg);
    cfg.setCountryCode("US");
    cfg.setCountryName("United States");
    cfg.setCurrency("$");
}
