var $ = require('common:widget/ui/jquery/jquery.js');
var helper = require('common:widget/ui/helper/helper.js');
/**
 * @author Cgy
 * @version 1.0.0
 * @description  
 *     基于css-ui.css生成气泡，样式参考http://ui.i18n.pro/demo/#bubble
 *     如果需要自定义样式，可在.ui-bubble-modId（对应modId）类名下来修改
 *     如果需要自定义z-index, 需要在样式后添加!important
 *     
 * 用法： var demo = $("#test").bubble(opt);
 *        // demo对象为jQuery对象，指向生成的气泡对象
 *
 * 
 * 
    opt = {
		'wrapOpt': {
			// 用于统计参数和自定义样式，为空时自动向上遍历获得最近的modId，可选，推荐必填
			'modId': '', 
			// 用于控制arrow的方向，共有四个值t,b,l,r,默认为t，可选
			'direc': 't', 
			// 主体内容前面的额外内容，可为HTML字符串，可选
			'before': '', 
			// 主体内容后面的额外内容，可为HTML字符串，可选
			'after': '', 
			// 主体内容，可为HTML字符串，必填
			'content': '',
			// 气泡皮肤类名（ui-bubble--skin），可选
			'skin': ''
		}, // 以下为可选
		'moreOpt': {
			// 更多链接的位置，r,t,b,l. 默认值r。可选. 参考http://ui.i18n.pro/demo/#arrow
			'direc': '',
			// 更多链接align的位置，aa,av,ah. 默认值av。可选. 参考http://ui.i18n.pro/demo/#arrow
			'microDirec': '',
			// 更多链接的链接， 默认值#。可选
			'url': '',
			// 更多链接的内容，为空时不显示更多链接，可选
			'content': ''
		},
		'btnOpt': {
			// 按钮的位置，l，r，可选。默认值r. 参考http://ui.i18n.pro/demo/#button
			'direc': 'r',
			// 按钮的内容，为空时不显示按钮，可选
			'content': ''
		},
		'pos': {
	        'left': 20, // 气泡位置距离生成气泡元素左上角的距离，可选. 默认值0
	        'top': 10  // 可选. 默认值0
	    },
	    'callback': {// 事件绑定通过类名和方法的映射。当点击拥有类名的a标签时触发对应事件。可选
            'ui-bubble_close': function() {
                alert("close")
            },
            'ui-bubble_more': function() {
                alert("more")
            },
            'ui-btn': function() {
                alert("btn")
            }
        }
	}
 *
 */
(function() {
	var _defaultTpl = '<div class="ui-bubble ui-bubble-#{direc} ui-bubble-#{modId} #{skin}" log-mod="#{modId}" style="display: none;z-index: #{zIndex};" id="bubble#{modId}"><b class="ui-arrow ui-bubble_out"></b><b class="ui-arrow ui-bubble_in"></b><a href="#" class="ui-bubble_close" onclick="return false" hidefocus="true">×</a>#{before}<p class="ui-bubble_t">#{content}#{more}</p>#{btn}#{after}</div>',
		_moreTpl = '<a href="#{url}" class="ui-bubble_more"><b class="ui-arrow ui-arrow-#{direc} ui-arrow-#{microDirec}"></b>#{content}</a>',
		_btnTpl = '<span class="ui-btn_bar ui-btn_bar-#{direc}"><a href="#" onclick="return false" class="ui-btn" hidefocus="true">#{content}</a></span>';
	var _defaultOpt = {
		'wrapOpt': {
			'modId': '', 
			'direc': 't', 
			'before': '',
			'after': '',
			'content': '',
			'more': '',
			'btn': '',
			'skin': ''
		},
		'moreOpt': {
			'direc': 'r',
			'microDirec': 'av',
			'url': '#',
			'content': ''
		},
		'btnOpt': {
			'direc': 'r',
			'content': ''
		}, 
		'pos': {
			'left': 0,
			'top': 0
		},
		'callback': null
	};

	var _data = [];// 所有使用本组件生成的气泡都放于该数组中，用于位置同步

	/**
	 * 同步气泡和生成气泡对象的位置
	 * 初始化监听器，每500毫秒查询一下每个生成气泡的对象是否位置发生变化
	 * 如果气泡或者生成气泡对象有一个display为none的话，气泡位置不发生变化
	 */
	function init() {
		setTimeout(function() {
			var i = 0,
				tmp = null,
				offset = null,
				toObj = null,
				fromObj = null,
				len = _data.length;

			for (; i < len; i++) {
				tmp = _data[i];
				toObj = tmp.toObj;
				fromObj = tmp.fromObj;
				offset = fromObj.offset();

				if (toObj.css("display") === "none" || fromObj.css("display") === "none") {
					continue;
				}
				if (offset.left == tmp["oldPos"].left && offset.top == tmp["oldPos"].top) {

				} else {
					_data[i] = fixPosition(toObj, fromObj, tmp.pos);
				}
			}
			setTimeout(arguments.callee, 500);
		}, 500);
	}

	/**
	 * 
	 * @param  {object} opt 配置参数
	 * @return {string}     拼接好的html模版
	 */
	function getHtml(opt) {
		var wrapOpt = opt["wrapOpt"],
			moreOpt = opt["moreOpt"],
			btnOpt = opt["btnOpt"];

		moreOpt && (wrapOpt.more = moreOpt.content ? helper.replaceTpl(_moreTpl, moreOpt) : "");
		btnOpt && (wrapOpt.btn = btnOpt.content ? helper.replaceTpl(_btnTpl, btnOpt) : "");
		wrapOpt["skin"] = wrapOpt["skin"] ? ("ui-bubble--" + wrapOpt["skin"]) : "";
		return helper.replaceTpl(_defaultTpl, wrapOpt);
	}
	/**
	 * 绑定事件
	 * @param  {jQuery} wrap 事件代理对象
	 * @param  {object} opt  类名和对应触发事件映射
	 * 
	 */
	function bindEventHandler(wrap, opt) {
		wrap.on("click", ".ui-bubble_close", function(e) {
			wrap.hide();
		});

		if (!opt) return;
		wrap.on("click", "a", function(e) {
			var that = $(this),
				i;
			for (i in opt) {
				if (that.hasClass(i)) {
					opt[i].call(that, wrap, e);
				}
			}
			
		});
	}

	/**
	 * toObj相对于fromObj的左上角和pos对象整合后定位
	 * @param  {jQuery} toObj   气泡对象
	 * @param  {jQuery} fromObj 生成气泡对象
	 * @param  {object} pos     偏移位置信息
	 * @return {object}         {气泡对象，生成气泡对象，偏移位置，生成气泡对象当前位置信息}
	 */
	function fixPosition(toObj, fromObj, pos) {
		var offset = fromObj.offset(),
			curPos = offset;

		pos = pos || {
			left: 0,
			top: 0
		};
		curPos.left += pos.left;
		curPos.top += pos.top;
		toObj.offset(curPos);

		return {
			toObj: toObj,
			fromObj: fromObj,
			pos: pos,
			oldPos: offset
		};
	}

	$.fn.extend({
		bubble: function(opt) {
			var _wrap = $("#bubbleUIWrap"),
				origin = $(this),
				that = null;
			if (_wrap.length) {} else {
				$(document.body).append('<div class="l-wrap" id="bubbleUIWrap"></div>');
				_wrap = $("#bubbleUIWrap");
			}

			if (opt["wrapOpt"].modId === "") {
				opt["wrapOpt"].modId = this.closest("[log-mod]").attr("log-mod");
			}

			$.extend(true, _defaultOpt, opt);
			_defaultOpt["wrapOpt"].zIndex = parseInt(0 + origin.css("z-index"), 10) + 1;
			$(getHtml(_defaultOpt)).appendTo(_wrap);
			that = _wrap.find(".ui-bubble-" + opt["wrapOpt"].modId);
			bindEventHandler(that, _defaultOpt["callback"]);
			_data.push(fixPosition(that, origin, _defaultOpt["pos"]));

			return that;
		}
	});

	init();
})();