﻿/**
 * @fileOverview
 * @author amoschen
 * @version
 * Created: 13-8-5 上午11:55
 */
BizQQWPA.define('wpa.SelectPanel', 'lang.browser,util.Style,util.className,util.events,util.offset,util.css,util.proxy,lang.extend', function(require){
    var Style = require('Style'),
        className = require('className'),
        events = require('events'),
        offset = require('offset'),
        browser = require('browser'),
        css = require('css'),
        proxy = require('proxy'),
        extend = require('extend');

    var NODE_TYPE_ELEMENT = 1;

    var doc = document;

    var findById = function(parent, id){
        var append = function(host, tail){
                for(var i= 0, len= tail.length; i !== len; host.push(tail[i++])){}
                return host;
            },
            children = append([], parent.childNodes),
            len = children.length,
            pos = 0,
            curNode,
            ret = null;

        while(len > pos){
            curNode = children[pos++];

            if(curNode.nodeType !== NODE_TYPE_ELEMENT){
                continue;
            }

            if(curNode.getAttribute('id') === id){
                ret = curNode;
                break;
            }

            append(children, curNode.childNodes);
            len = children.length;
        }

        return ret;
    };

    /**
     * Default settings
     * @type {Object}
     */
    var SETTINGS = {
        // container where panel to be contained
        container: doc.getElementsByTagName('body')[0],

        // template of panel
        template: [
            '<div class="WPA3-SELECT-PANEL">',
                '<div class="WPA3-SELECT-PANEL-TOP">',
                    '<a id="WPA3-SELECT-PANEL-CLOSE" href="javascript:;" class="WPA3-SELECT-PANEL-CLOSE"></a>',
                '</div>',
                '<div class="WPA3-SELECT-PANEL-MAIN">',
                    '<p class="WPA3-SELECT-PANEL-GUIDE">请选择发起聊天的方式：</p>',
                    '<div class="WPA3-SELECT-PANEL-SELECTS">',
                        '<a id="WPA3-SELECT-PANEL-AIO-CHAT" href="javascript:;" class="WPA3-SELECT-PANEL-CHAT WPA3-SELECT-PANEL-AIO-CHAT">',
                            '<span class="WPA3-SELECT-PANEL-QQ WPA3-SELECT-PANEL-QQ-AIO"></span>',
                            '<span class="WPA3-SELECT-PANEL-LABEL">QQ帐号聊天</span>',
                        '</a>',
                        '<a id="WPA3-SELECT-PANEL-ANONY-CHAT" href="javascript:;" class="WPA3-SELECT-PANEL-CHAT WPA3-SELECT-PANEL-ANONY-CHAT">',
                            '<span class="WPA3-SELECT-PANEL-QQ WPA3-SELECT-PANEL-QQ-ANONY"></span>',
                            '<span class="WPA3-SELECT-PANEL-LABEL">匿名聊天</span>',
                        '</a>',
                    '</div>',
                '</div>',
                '<div class="WPA3-SELECT-PANEL-BOTTOM">',
                    '<a target="_blank" href="https://im.qq.com" class="WPA3-SELECT-PANEL-INSTALL">安装QQ</a>',
                '</div>',
            '</div>'
        ].join(''),

        // panel's style
        cssText: [
            '.WPA3-SELECT-PANEL { z-index:2147483647; width:463px; height:292px; margin:0; padding:0; border:1px solid #d4d4d4; background-color:#fff; border-radius:5px; box-shadow:0 0 15px #d4d4d4;}',
            // css reset
            '.WPA3-SELECT-PANEL * { position:static; z-index:auto; top:auto; left:auto; right:auto; bottom:auto; width:auto; height:auto; max-height:auto; max-width:auto; min-height:0; min-width:0; margin:0; padding:0; border:0; clear:none; clip:auto; background:transparent; color:#333; cursor:auto; direction:ltr; filter:; float:none; font:normal normal normal 12px "Helvetica Neue", Arial, sans-serif; line-height:16px; letter-spacing:normal; list-style:none; marks:none; overflow:visible; page:auto; quotes:none; -o-set-link-source:none; size:auto; text-align:left; text-decoration:none; text-indent:0; text-overflow:clip; text-shadow:none; text-transform:none; vertical-align:baseline; visibility:visible; white-space:normal; word-spacing:normal; word-wrap:normal; -webkit-box-shadow:none; -moz-box-shadow:none; -ms-box-shadow:none; -o-box-shadow:none; box-shadow:none; -webkit-border-radius:0; -moz-border-radius:0; -ms-border-radius:0; -o-border-radius:0; border-radius:0; -webkit-opacity:1; -moz-opacity:1; -ms-opacity:1; -o-opacity:1; opacity:1; -webkit-outline:0; -moz-outline:0; -ms-outline:0; -o-outline:0; outline:0; -webkit-text-size-adjust:none; font-family:Microsoft YaHei,Simsun;}',
            '.WPA3-SELECT-PANEL a { cursor:auto;}',
            // panel top
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-TOP { height:25px;}',
            // close button
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-CLOSE { float:right; display:block; width:47px; height:25px; background:url(https://combo.b.qq.com/crm/wpa/release/3.3/wpa/views/SelectPanel-sprites.png) no-repeat;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-CLOSE:hover { background-position:0 -25px;}',
            // panel main
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-MAIN { padding:23px 20px 45px;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-GUIDE { margin-bottom:42px; font-family:"Microsoft Yahei"; font-size:16px;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-SELECTS { width:246px; height:111px; margin:0 auto;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-CHAT { float:right; display:block; width:88px; height:111px; background:url(https://combo.b.qq.com/crm/wpa/release/3.3/wpa/views/SelectPanel-sprites.png) no-repeat 0 -80px;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-CHAT:hover { background-position:-88px -80px;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-AIO-CHAT { float:left;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-QQ { display:block; width:76px; height:76px; margin:6px; background:url(https://combo.b.qq.com/crm/wpa/release/3.3/wpa/views/SelectPanel-sprites.png) no-repeat -50px 0;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-QQ-ANONY { background-position:-130px 0;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-LABEL { display:block; padding-top:10px; color:#00a2e6; text-align:center;}',
            // panel bottom
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-BOTTOM { padding:0 20px; text-align:right;}',
            '.WPA3-SELECT-PANEL .WPA3-SELECT-PANEL-INSTALL { color:#8e8e8e;}'
        ].join(''),

        // use modal or not
        modal: true
    };

    // add confirm style to page
    Style.add('_WPA_SELECT_PANEL_STYLE', SETTINGS.cssText);

    var SelectPanel = function(opts){
        this.opts = extend({}, opts, SETTINGS);
        this.render();
    };

    SelectPanel.prototype = {
        render: function(){
            var panel = this,
                opts = this.opts,
                body = this.container = opts.container;

            // create dom element
            var frag = doc.createElement('div'),
                frame;
            frag.innerHTML = opts.template;
            this.$el = frame = frag.firstChild;

            events.addEvent(findById(frame, 'WPA3-SELECT-PANEL-CLOSE'), 'click', function(){
                panel.remove();
                opts.onClose && opts.onClose();
            });

            events.addEvent(findById(frame, 'WPA3-SELECT-PANEL-AIO-CHAT'), 'click', function(){
                panel.remove();
                opts.onAIOChat && opts.onAIOChat();
            });

            events.addEvent(findById(frame, 'WPA3-SELECT-PANEL-ANONY-CHAT'), 'click', function(){
                panel.remove();
                opts.onAnonyChat && opts.onAnonyChat();
            });

            // insert into dom
            (function(){
                try{
                    body.appendChild(frame);
                } catch(e){
                    setTimeout(arguments.callee, 1);
                    return;
                }

                // when frame is inserted into dom

                // render modal
                if(opts.modal){
                    panel.renderModal();
                }

                // set position
                // only node is in document can we get computedStyles correctly
                panel.setCenter();
            })();
        },

        show: function(){
            this.css('display', 'block');
            this.modal && css(this.modal, 'display', 'block');
            return this;
        },

        hide: function(){
            this.css('display', 'none');
            this.modal && css(this.modal, 'display', 'none');
            return this;
        },

        remove: function(){
            this.$el.parentNode.removeChild(this.$el);
            this.modal && this.modal.parentNode.removeChild(this.modal);
            return this;
        },

        css: function(){
            var args = [this.$el].concat(Array.prototype.slice.call(arguments));
            return css.apply(this, args);
        },

        setCenter: function(){
            // set position to make sure it would not be affected by parent node
            this.css({
                position: 'absolute', // make it compatible for ie
                top: '50%',
                left: '50%'
            });

            // standard mode css reset
            var styles = {
                position: 'fixed', // reset to fixed in standard mode
                marginLeft: '-' + this.outerWidth()/2 + 'px',
                marginTop: '-' + this.outerHeight()/2 + 'px'
            };

            // ie6 or quirk mode css reset
            var isQuirk = doc.compatMode === 'BackCompat';
            if( (browser.msie && parseInt(browser.version, 10) < 7) || isQuirk){
                // css reset
                styles.position = 'absolute';
                styles.marginTop = 0;
                var top = styles.top = (offset.getClientHeight() - this.outerHeight())/2;

                // scroll update
                setInterval(proxy(this.$el, function(){
                    this.style.top = offset.getScrollTop() + top + 'px';
                }), 128);
            }

            // batch set styles
            this.css(styles);
        },

        renderModal: function(){
            var container = this.container,
                width = css(container, 'width'),
                height = css(container, 'height'),
                overflow = css(container, 'overflow');

            var modalLayer = doc.createElement('div'),
                styles = {
                    position: 'fixed',
                    top: 0,
                    left: 0,
                    zIndex: 2147483647,
                    width: offset.getClientWidth() + 'px',
                    height: offset.getClientHeight() + 'px',
                    backgroundColor: 'white',
                    opacity: 0.1,
                    filter: 'alpha(opacity=10)'
                };

            // ie6 or quirk mode css reset
            var isQuirk = doc.compatMode === 'BackCompat';
            if( (browser.msie && parseInt(browser.version, 10) < 7) || isQuirk){
                // css reset
                styles.position = 'absolute';

                // scroll update
                setInterval(proxy(modalLayer, function(){
                    this.style.top = offset.getScrollTop() + 'px';
                }), 128);
            }

            css(modalLayer, styles);
            container.insertBefore(modalLayer, this.$el);
            this.modal = modalLayer;

            events.addEvent(window, 'resize', proxy(modalLayer, function(){
                css(this, {
                    width: offset.getClientWidth() + 'px',
                    height: offset.getClientHeight() + 'px'
                });
            }));
        },

        outerWidth: function(){
            return this.$el.offsetWidth;
        },

        outerHeight: function(){
            return this.$el.offsetHeight;
        }
    };

    return SelectPanel;
});/**
 * Created with JetBrains WebStorm.
 * User: amoschen
 * Date: 13-1-7
 * Time: 下午7:34
 * To change this template use File | Settings | File Templates.
 */
BizQQWPA.define('util.css', 'util.contains', function(require){
    var contains = require('contains');

    var getStyle = document.defaultView && document.defaultView.getComputedStyle ?
        // for standard W3C method
        function(node, style){
            //font-wight而非fontWight
            style = style.replace(/([A-Z])/g,"-$1").toLowerCase();

            //获取样式对象并获取属性（存在的话）值
            var s = document.defaultView.getComputedStyle(node,"");
            return s && s.getPropertyValue(style);
        }:
        // for ie
        function(node, style){
            return node.currentStyle[style];
        };

    var inDom = function(node, fn){
        if(!contains(node, document)){
            return fn();
        }

        var inVisible = {
                opacity: 0,
                filter: 'alpha(opacity=0)'
            },
            parent = node.parentNode,
            nextSibling = node.nextSibling,
            div = document.createElement('div'),
            returnValue;

        div.appendChild(node);
        css(div, inVisible);
        css(node, inVisible);
        document.body.appendChild(div);

        returnValue = fn();

        nextSibling ? parent.insertBefore(node, nextSibling) : parent.appendChild(node);
        div.parentNode.removeChild(div);

        return returnValue;
    };

    /**
     * css Node's style operation
     * @param {HTMLElement} node Node to be set
     * @param {string|object} style Style name or the styles' pairs
     * @param {string} [value] Style value
     * @retrun {string} Style value, only with string type style  and no value
     */
    var css = function(node, style, value){
        var cssText;

        if(!value){
            // get style
            if(typeof style === 'string'){
                return inDom(node, function(){
                    return getStyle(node, style);
                });
            }

            // type validation
            if(typeof style !== 'object'){
                new TypeError('Arg style should be string or object');
            }

            // batch set
            cssText = [];
            for(var styleName in style){
                cssText.push(styleName + ':' + style[styleName]);
            }
            cssText = cssText.join(';');
        } else {
            cssText = style + ':' + value;
        }

        // set style with value
        cssText = cssText.replace(/([A-Z])/g,"-$1").toLowerCase();
        node.style.cssText += ';' + cssText; // cssText ends up without a semicolon in ie
        return node;
    };

    return css;
});/**
 * @fileOverview
 * @author amoschen
 * @version
 * Created: 12-8-22 下午8:37
 */
BizQQWPA.define('lang.extend', 'lang.each,lang.typeEnhance', function(require){
    var each = require('each'),
        typeEnhance = require('typeEnhance');

    return function(){
        var args = Array.prototype.slice.call(arguments),
            deep = false,
            base = args.shift(),
            override = typeEnhance.type(args[args.length - 1]) === 'boolean' ? args.pop() : false;

        if(base === true){
            deep = true;
            base = args.shift();
        }

        // plain merge
        var extend = override ?
                function(base, ext){
                    each(ext, function(i, p){
                        base[i] = p
                    });
                }:
                function(base, ext){
                    each(ext, function(i, p){
                        if(typeof base[i] !== 'undefined'){
                            return;
                        }

                        base[i] = p;
                    });
                };

        // recursive merge
        var extendRecursive = override ?
                function(base, ext){
                    each(ext, function(i, p){
                        if(typeEnhance.type(p) !== 'object'){
                            base[i] = p;
                            return;
                        }

                        base[i] = arguments.callee({}, p);
                    });
                }:
                function(base, ext){
                    each(ext, function(i, p){
                        if(typeof base[i] !== 'undefined'){
                            return;
                        }

                        if(typeEnhance.type(p) !== 'object'){
                            base[i] = p;
                            return;
                        }

                        base[i] = arguments.callee({}, p);
                    });
                };

        each(args, function(i, obj){
            deep ? extendRecursive(base, obj) : extend(base, obj);
        });

        return base;
    };
});/**
 * Created with JetBrains WebStorm.
 * User: amoschen
 * Date: 13-1-7
 * Time: 下午7:33
 * To change this template use File | Settings | File Templates.
 */
BizQQWPA.define('util.contains', function(){
    /**
     * contains Element contains another
     * @param {HTMLElement} node The node to be contained
     * @param {object} context The context in which the node is contained
     * @borrow jQuery.contains
     */
    return document.documentElement.contains ?
            function( node, context ) {
                var adown = node.nodeType === 9 ? node.documentElement : node,
                    bup = context && context.parentNode;
                return node === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
            } :
            document.documentElement.compareDocumentPosition ?
                function( node, context ) {
                    return context && !!( node.compareDocumentPosition( context ) & 16 );
                } :
                function( node, context ) {
                    while ( (context = context.parentNode) ) {
                        if ( context === node ) {
                            return true;
                        }
                    }
                    return false;
                };
});