/*
 * @author Shanpeng
 * @website:http://www.ilovejs.net
 * @e-mail:supersha@foxmail/shanpeng@taobao.com/supershafeng@gmail.com
 * @QQ:770104121
 * @my word:Here,believe what browsers display,and believe yourself
 */
////////////////////// Javascript's code below ///////////////////////
;(function(global){
    var addListener = function(elem, type, handle){
        if (elem.addEventListener) {
            elem.addEventListener(type, handle, false);
        }
        else if (elem.attachEvent) {
            elem.attachEvent("on" + type, handle);
        }
        else {
            elem["on" + type] = handle;
        }
    }
	
    var pageX = function(elem){return elem.offsetParent ? elem.offsetLeft + pageX(elem.offsetParent) : elem.offsetLeft;}
    var pageY = function(elem){return elem.offsetParent ? elem.offsetTop + pageY(elem.offsetParent) : elem.offsetTop;}
    var getHeight = function(elem){return parseInt(elem.offsetHeight || elem.clientHeight);}
    var getWidth = function(elem){return parseInt(elem.offsetWidth || elem.clientWidth);}
    
    var getFinalStyle = function(el, attr){
        var style = null;
        if (el.currentStyle) { //IE
            style = el.currentStyle[attr];
        }
        else if (window.getComputedStyle) { //W3C
            style = window.getComputedStyle(el, null)[attr];
        }
        else {
            style = el.style[attr];
        }
        return (style === "auto" || !style || style ==="medium") ? 0 : style;
    }
    
    var $ = function(id){
        return typeof id === "string" ? document.getElementById(id) : id;
    }
    
    var createBGWrap = function(width, height, left, top){
        var div = document.createElement("div");
        var ds = div.style;
        div.id = "fireTest";
        ds.left = left + "px";
        ds.top = top + "px";
        ds.width = width + "px";
        ds.height = height + "px";
        return div;
    }
    
    var createMarginParddingWrap = function(){
        var div = document.createElement("div");
		div.id="MarginPaddingDiv";
        return div;
    }
    
    var cloneMarginPaddingWrap = function(elem, id, width, height, left, top){
        var es = elem.style;
        elem.id = id;
        es.width = width + "px";
        es.height = height + "px";
        es.left = left + "px";
        es.top = top + "px";
        return elem;
    }
	
	var createToolTip=function(){
		var div=document.createElement("div");
		var ds=div.style;
		div.id = "fireTestToolTip";
		ds.visibility="hidden";
		return div;
	}
    
    var showToolTip = function(elem, tt,w, h, x, y, MPObject){
        var ds = tt.style;
		ds.visibility="visible";
        ds.left = (x - MPObject.ml) + "px";
        ds.top = (y + h + MPObject.mb) + "px";
        var temp = "";
        temp = "Tag:" + elem.nodeName + "<br />";
        temp += "w:" + w + "px<br />";
        temp += "h:" + h + "px<br />";
        temp += "x:" + x + "px<br />";
        temp += "y:" + y + "px<br />";
        temp += "padding:" + MPObject.pt + "px " + MPObject.pr + "px " + MPObject.pb + "px " + MPObject.pl + "px<br />";
        temp += "margin:" + MPObject.mt + "px " + MPObject.mr + "px " + MPObject.mb + "px " + MPObject.ml + "px<br />";
		temp += "border-width:"+ MPObject.bt + "px " + MPObject.br + "px " + MPObject.bb + "px " + MPObject.bl + "px";
        tt.innerHTML = temp;
    }
	
	var hideToolTip=function(id){
		$(id).style.visibility="hidden";
	}
    
    var getMarginPadding = function(elem){
        return {
            "ml": parseInt(getFinalStyle(elem, "marginLeft")),
            "mr": parseInt(getFinalStyle(elem, "marginRight")),
            "mt": parseInt(getFinalStyle(elem, "marginTop")),
            "mb": parseInt(getFinalStyle(elem, "marginBottom")),
            "pl": parseInt(getFinalStyle(elem, "paddingLeft")),
            "pr": parseInt(getFinalStyle(elem, "paddingRight")),
            "pt": parseInt(getFinalStyle(elem, "paddingTop")),
            "pb": parseInt(getFinalStyle(elem, "paddingBottom")),
            "bl": parseInt(getFinalStyle(elem, "borderLeftWidth")),
            "br": parseInt(getFinalStyle(elem, "borderRightWidth")),
            "bt": parseInt(getFinalStyle(elem, "borderTopWidth")),
            "bb": parseInt(getFinalStyle(elem, "borderBottomWidth"))
        }
    }
    
    var stopPropagation = function(ev){
        if (ev && ev.stopPropagation) {
            ev.stopPropagation();
        }
        else {
            window.event.cancelBubble = true;
        }
    }
    
    var fireTest = function(){
        var allElems = document.body.getElementsByTagName("*");
        var MPDiv = createMarginParddingWrap();
		var tooltip=createToolTip();
		document.body.appendChild(tooltip);
        document.body.appendChild(MPDiv);
        for (var i = 0, len = allElems.length; i < len; i++) {
            (function(index){
				var el = allElems[index];
                if (el.nodeType === 1 && el.id !== "fireTestSwidth") {
                    addListener(el, "mouseover", function(e){
                       overHandle(e,el,MPDiv,tooltip);
                    });
                    addListener(el, "mouseout",function(e){
                       outHandle(e);
                    });
                }
			})(i);
        }
    }
    
    var overHandle = function(e,el,MPDiv,tooltip){
		if(!fireTest.on){return;}
        var db = document.body;
        var MPObj = getMarginPadding(el);
        var h = getHeight(el);
        var w = getWidth(el);
        var x = pageX(el);
        var y = pageY(el);
		
        db.appendChild(createBGWrap(w, h, x, y));
        //Margin
        if (MPObj.ml) {db.appendChild(cloneMarginPaddingWrap(MPDiv.cloneNode(true), "margin_left", MPObj.ml, h, x - MPObj.ml, y));}
        if (MPObj.mr) {db.appendChild(cloneMarginPaddingWrap(MPDiv.cloneNode(true), "margin_right", MPObj.mr, h, (w + x), y));}
        if (MPObj.mt) {db.appendChild(cloneMarginPaddingWrap(MPDiv.cloneNode(true), "margin_top", MPObj.ml + MPObj.mr + w, MPObj.mt, x - MPObj.ml, y - MPObj.mt));}
        if (MPObj.mb) {db.appendChild(cloneMarginPaddingWrap(MPDiv.cloneNode(true), "margin_bottom", MPObj.ml + MPObj.mr + w, MPObj.mb, x - MPObj.ml, y + h));}
        //Padding
        if (MPObj.pt) {db.appendChild(cloneMarginPaddingWrap(MPDiv.cloneNode(true), "padding_top", w - MPObj.bl - MPObj.br, MPObj.pt, x + MPObj.bl, y + MPObj.bt));}
        if (MPObj.pr) { db.appendChild(cloneMarginPaddingWrap(MPDiv.cloneNode(true), "padding_right", MPObj.pr, h - MPObj.bt - MPObj.bb, x + w - MPObj.br - MPObj.pr, y + MPObj.bt));}
        if (MPObj.pl) {db.appendChild(cloneMarginPaddingWrap(MPDiv.cloneNode(true), "padding_left", MPObj.pl, h - MPObj.bt - MPObj.bb, x + MPObj.bl, y + MPObj.bt));}
        if (MPObj.pb) {db.appendChild(cloneMarginPaddingWrap(MPDiv.cloneNode(true), "padding_bottom", w - MPObj.bl - MPObj.br, MPObj.pb, x + MPObj.bl, y + h - MPObj.bb - MPObj.pb));}
        //ToolTip
        showToolTip(el,tooltip, w, h, x, y, MPObj);
        stopPropagation(e);
    }
    var outHandle = function(e){
		if(!fireTest.on){return;}
        var db = document.body;
        if ($("fireTest")) { db.removeChild($("fireTest"));}
        //Margin
        if ($("margin_left")) {db.removeChild($("margin_left"));}
        if ($("margin_right")) {db.removeChild($("margin_right"));}
        if ($("margin_top")) {db.removeChild($("margin_top"));}
        if ($("margin_bottom")) {db.removeChild($("margin_bottom"));}
        //Padding
        if ($("padding_top")) {db.removeChild($("padding_top"));}
        if ($("padding_right")) {db.removeChild($("padding_right"));}
        if ($("padding_left")) {db.removeChild($("padding_left"));}
        if ($("padding_bottom")) {db.removeChild($("padding_bottom"));}
		//ToolTip
        if($("fireTestToolTip")){hideToolTip("fireTestToolTip");}
        stopPropagation(e);
    }
    addListener(window,"load",function(){
		//dynamic download a css file
		var link=document.createElement("link");
		link.rel="stylesheet";
		link.type="text/css";
		link.href="http://www.ilovejs.net/lab/fireTest/fireTest.css";
		document.getElementsByTagName("head")[0].appendChild(link);
		//fireTestSwidth
		var div=document.createElement("div");
		div.id="fireTestSwidth";
		div.innerHTML="FireTest On";
		addListener(div,"click",function(e){
			if(fireTest.on){
				fireTest.on=false;
				div.innerHTML="FireTest On";
				div.style.backgroundColor="#f00";
			}else{
				fireTest.on=true;
				div.innerHTML="FireTest Off";
				div.style.backgroundColor="#0f0";
			}
		});
		document.body.appendChild(div);
		fireTest();
	});
})(this);
