var g_max_ad_container_height = 320;
var CURRENT_ELEMENT;
var LAST_HIT_ELEMENT;   /* 记录上次点击元素 */
var SELECTED_ELEMENT;
var g_element_rules = null;

/* 记录设备点击屏幕的坐标*/
var last_point = {
    left: 0,
    top: 0
};

/* 获取元素相对于浏览器的top */
function getTop(e){
    var offset=e.offsetTop;
    if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
    return offset;
}

/* 获取元素相对于浏览器的left */
function getLeft(e){
    var offset=e.offsetLeft;
    if(e.offsetParent!=null) offset+=getLeft(e.offsetParent);
    return offset;
}

/* 找到一个合适的可选择元素 */
function find_fit_element(target) {

    /* 遍历,获取当前触点所在容器 */
    while(target.parentElement != null && target.parentElement.offsetHeight < g_max_ad_container_height) {
        if(target.parentElement) {
        }
        target = target.parentElement;
    }
    /* 一些元素的高度是0,回朔到其子元素 */
    if(target.offsetHeight == 0 &&  target.children.length > 0) {

       for(var i = 0; i < target.children.length; i ++) {
            var c = target.children[i];
            /* if(c.tagName.length >=10) continue;  skip some strange element */
            if(c.offsetHeight < g_max_ad_container_height && c.offsetHeight >= g_min_ad_container_height) {
                target = c;
                break;
            }
       }
    }
    return target;
}
function native_touch_to_element(x,y,height,width) {
    x *= (window.innerWidth / width);
    y *= (window.innerHeight / height);

    last_point.left = x;
    last_point.top = y;
    var target = document.elementFromPoint(x, y);
    return target;
}

/* 通过元素本身生成元素选择规则 */
function gen_element_rule(el) {
   var rule = '';
    var id = el.id;
    var cl = '';
    var host =  window.location.host;
    var tagName = el.tagName;
    var attrs = el.getAttributeNames();
    var selector = '';
    var extra = '';

    var attrList = '';
    for(var i = 0; i < el.classList.length;i++) {
        cl +=  '.' +  el.classList.item(i);
    }

    for(var j = 0 ; j < attrs.length; j++) {
      var fuzzy = false;
      var hasVaule = true;
      var name = attrs[j];
      var value = el.getAttribute(name);
      if(name == 'class') {
        continue;
      }

      if(name == 'id') {
         continue;
      }
      if(name == 'title') {
         continue;
      }

      if(name == 'style') {

        if(!value) continue;
      }

      if(!value) {
          hasVaule = false;
      }
      if(name.indexOf('src') >= 0 || name.indexOf('href') >= 0 || name.indexOf('source') >= 0) {
          var p = value.indexOf('?');
          if(p>0) {
            value = value.substring(0,p);
            fuzzy = true;
          }

      }
      if(!hasVaule) {
          attrList += '[' + name + ']';
      }
      else if(!fuzzy) {
          attrList += '[' + name + '=' + '\'' + value + '\'' + ']';
      } else {
          attrList += '[' + name + '^=' + '\'' + value + '\'' + ']';
      }

    }
    if(tagName) {
        selector += tagName;
    }
    if(id) {
      selector += '#' + id;
    }

    if(cl) {
      selector += cl;
    }

    if(attrList) {
      selector += attrList;
    }

    var elements = document.querySelectorAll(selector);

    if(true || elements.length > 2) {
        extra = '->m:' + getLeft(el)+ ':' + getTop(el) + ':' + el.offsetWidth + ':' + el.offsetHeight;
    } else {
        extra = "->m";
    }

    if(host) {
      rule = host + '##' + selector
    } else {
      rule = '##' + selector;
    }
    rule += extra;
    return rule;

}

function do_execute_rule(rule){
    var selector = rule;
    /**
     *  扩展规则1： !10  符合条件的元素的格式，当符合元素个数超过一定数量，判定为成批的牛皮癣广告
     *  扩展规则2: !200x30 符合条件的广告过多，通过元素坐标进行限定.
     */
    var pos = rule.indexOf("->");   /* 扩展规则的分隔符号 */
    var min = 0;
    var left = 0;
    var top = 0;
    var w = 0;
    var h = 0;
    var type = 0;  /* 0 - 普通规则 1 - 扩展规则1 ( rule!num ) 2- 扩展规则2  */
    var isMark  = false;

    if(pos > 0) {   /* 扩展参数   */
        var param = rule.substring(pos+2);
        if(param && param.indexOf('m') >= 0) {
            isMark = true;
        }
        if(param.indexOf(':') > 0) {
            var p = param.split(':');
            if(param.indexOf('m') < 0) {
                left = parseInt(p[0]);
                top = parseInt(p[1]);
                w = parseInt(p[2]);
                h = parseInt(p[3]);
            } else {  /* rule!m:x:y*/
                var m = parseInt(0);
                left = parseInt(p[1]);
                top = parseInt(p[2]);
                w = parseInt(p[3]);
                h = parseInt(p[4]);
                if(m == 'm') {
                    isMark = true;
                }
                type = 2;
            }

        }
        else {
            min = parseInt(param);
            type = 1;
        }
        selector = rule.substring(0,pos);
    }

    var origin_selector = selector;
    var elements = document.querySelectorAll(selector);

    if(elements.length > 0) {

        if(elements.length > 1 && (top > 0 || left > 0) ) {
             type = 2;
        }
        else if(min > 0 && elements.length < min) {
            return;
        } else if(min > 0){
            type = 1;
        } else {
            type = 0;      /*  如果可以精确命中，则无需进行深度遍历 */
        }
    }

    /*  没有命中，对用户标识的广告进行深度检测 */
    if(isMark && elements.length == 0) {
        var tag = "";
        var p = selector.indexOf('#');
        var p1 = selector.indexOf('.');
        var p2 = selector.indexOf('[');

        if((p > 0 && p2 < 0) || (p > 0 && p < p2))  {
            tag = selector.substring(0,p);
        }

        if(p < 0 && p1 > 0 && (p2 < 0 || p1 < p2)) {
            tag = selector.substring(0,p1);
        }

        if(p < 0 && p1 < 0 && p2 > 0) {
            tag = selector.substring(0,p2);
        }

        if(p1 > 0 && p1 < p2) {   /* 移除根据id匹配的条件 */
            selector = selector.substring(p1);
            selector = tag + selector;
            if(selector != origin_selector) {
                elements = document.querySelectorAll(selector);
            }
        }

        /* 尝试移除类名匹配的条件 */
        if(elements.length == 0 && p2 > 0) {
             var attrs  = origin_selector.substring(p2);
             selector = tag + attrs;
             if(selector != origin_selector) {
                 elements = document.querySelectorAll(selector);
             }

            if(elements.length == 0 && attrs) {
                 selector = attrs;
                 elements = document.querySelectorAll(attrs);
            }

        }


        if(elements.length == 0 && tag  && type == 2) {
            selector = tag;
            elements = document.querySelectorAll(selector);
        }


        /* 普通的标识规则，如果命中结果过多则忽略之, */
        if(type == 0 && elements.length >= 3 || elements.length > 50 /* 限定元素个数防止性能低下 */) {
            return;
        }

    }

    for(var j= 0 ; j < elements.length; j++) {
        var target = elements[j];
        if(target && target.nodeType == 1) {
            var parent = target.parentElement;
            if(parent) {
                if(type == 1 && parent.tagName.toLowerCase() == "a") {
                    /*  扩展规则 批量删除牛皮癣广告 */
                    var url = parent.href;
                    var domain = get_main_domain(window.location.host);
                     /* 删除不属于本站的命中元素 */
                    if(url.indexOf("http") >= 0 && url.indexOf(domain) < 0) {
                       parent.removeChild(target);

                    }

                } else if(type == 2) {
                   /* 移除带有精确定位的元素 */
                   var _left = getLeft(target);
                   var _top = getTop(target);
                   var _w = target.offsetWidth;
                   var _h = target.offsetHeight;

                   if(Math.abs(_left - left) < 30 && Math.abs(_top - top) < 30 && _w == w && _h == h) {
                        parent.removeChild(target);
                        break;
                   }
                } else {
                    /* 移除普通元素 */
                    parent.removeChild(target);
                }

            }
        }
    }

    if(elements.length > 0) {
        add_hit_rule(rule);
    }
}

function add_hit_rule(rule){
        toApp.adBlockCount(rule);
}

function update_element_state() {
     if(true){
        if(!SELECTED_ELEMENT) {
            SELECTED_ELEMENT = CURRENT_ELEMENT;
            set_selected_state(SELECTED_ELEMENT,true);
        } else {
            if(SELECTED_ELEMENT == CURRENT_ELEMENT) {
                set_selected_state(SELECTED_ELEMENT,false);
                SELECTED_ELEMENT = null;
            }else{
                set_selected_state(SELECTED_ELEMENT,false);
                SELECTED_ELEMENT = CURRENT_ELEMENT;
                set_selected_state(SELECTED_ELEMENT,true);
            }
        }
    }else{
    }
}

function set_selected_state(target,selected){
    if(selected) {
        target.old_style = target.getAttribute("style");
        target.style = target.old_style + ";opacity:0.3;background-color:red;padding:2px";
    } else {
        if(target.old_style) {
            target.setAttribute("style",target.old_style);
        } else {
            target.setAttribute("style","");
        }
    }
}

function cancel_marked_element(){
    if(SELECTED_ELEMENT){
        set_selected_state(SELECTED_ELEMENT,false);
        SELECTED_ELEMENT = null;
    }
}

function adjustment_area(){
    if(CURRENT_ELEMENT) {
            if(CURRENT_ELEMENT.childElementCount > 0)  {
                console.log(">>>>>>>> fist child :" + CURRENT_ELEMENT.firstElementChild.tagName);
                CURRENT_ELEMENT = CURRENT_ELEMENT.firstElementChild;
                update_element_state();
            }
            else if(CURRENT_ELEMENT.nextElementSibling) {
                        CURRENT_ELEMENT = CURRENT_ELEMENT.nextElementSibling;
                        update_element_state();
            }
            else {
                CURRENT_ELEMENT = LAST_HIT_ELEMENT;
                update_element_state();
            }
        } else {
            console.log(">>>>> SELECTED ELEMENT IS NULL >>>>>");
        }
}

function run(x,y,h,w){
    var h=window.screen.height;
    var w=window.screen.width;
    var target= native_touch_to_element(x,y,h,w);
    target=find_fit_element(target);
    var rule= gen_element_rule(target);
    var host =  window.location.host;
    rule=rule.replace(host+"##","");
    do_execute_rule(rule);
}

function update_hit(x,y,h,w){
    var target= native_touch_to_element(x,y,h,w);
    target=find_fit_element(target);
    CURRENT_ELEMENT=target;
    LAST_HIT_ELEMENT = CURRENT_ELEMENT;
    update_element_state();
}

function preview(target,selected){
	if(selected){
		target.old_display=target.getAttribute("style");
		target.style = target.old_display+";display:none";
	}else{
		if(target.old_display){
			target.setAttribute("style",target.old_display);
		}else{
			target.setAttribute("style","");
		}
	}
}

function preview_view(selected){
        if(CURRENT_ELEMENT){
            preview(CURRENT_ELEMENT,selected);
        }
}

function genrule_element(){
    if(CURRENT_ELEMENT){
        cancel_marked_element();
        var rule= gen_element_rule(CURRENT_ELEMENT);
        var host =  window.location.host;
        var title = document.title;
        var hrule=rule.replace(host+"##","");
        do_execute_rule(hrule);
        toApp.adBlockRule(host,hrule,title);
        return rule;
    }
    return "";
}

function execute_element_rules() {
    var host = document.location.host;
    if(!g_element_rules) {
        g_element_rules = toApp.getRulesByDomain(host);
    }
    if(g_element_rules == "") {
        return;
    }
    try {g_element_rules = JSON.parse(g_element_rules);} catch(e){}
    for(var i= 0; i < g_element_rules.length; i++) {
        var rule = g_element_rules[i];
        do_execute_rule(rule);
    }
}
execute_element_rules();