/*
NAME: 
DESCRIPTION: 补铜桥;
PARAMETER:
    [
		{
			name : 'step_fliter',
			title : 'Step过滤',
			type : 'LineEdit',
			property : {tool_tip : 'unit'},
		},
		{
			name : 'erf',
			title : 'erf name',
			type : 'LineEdit',
			property : {tool_tip : 'erf'},
		},
		{
			name : 'layer_type',
			title : '工作层',
			type : 'ComboBox',
			property : {
			    size_policy:'Expanding,Fixed',
			    item_list:[
			        {name:'outer',text:'outer'},
			        {name:'inner',text:'inner'},
			        {name:'all',text:'all'}
			    ],
			    tool_tip:'分析模式必须设置,未设定则退出'
			},
			pack : {row:1,column:1},
		},
		{
            name : 'del_backup',
			title : '删除TL备份层',
            type : 'RadioBox',
            property : {
				item_list:[
					{name:'yes',text:'YES'},
					{name:'no',text:'NO'},
				],
				tool_tip:'是否自动保存料号开关'
			}
        },
		{
            name : 'auto_save',
			title : '自动保存',
            type : 'RadioBox',
            property : {
				item_list:[
					{name:'yes',text:'YES'},
					{name:'no',text:'NO'},
				],
				tool_tip:'是否自动保存料号开关'
			}
        }
	]
	
 VERSION_HISTORY:
	V1.00 2020-04-28 Scott Sun
	    1.新版本
		
 HELP:
 	<html><body bgcolor="#DDECFE">
		<font size="3" color="#003DB2"><p>功能简介</p></font>
		<p> 补铜桥 </p>
		<br>
		<font size="3" color="#003DB2"><p>参数配置</p></font>
		<p> 配置 </p>
		<br>
		<font size="3" color="#003DB2"><p>注意事项</p></font>
		<p> 无 </p>
		<br>
	</body></html>	
*/
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
console.log("==============================>JTG_PUB_pos_add_copper_bridge_aim");

// 引入模块 包
var $ = require('topcam.scriptfunc').argv();
var fs = require('fs');
var _ = require('lodash');
var mode = $.ikm ? "topcam" : "aimdfm";
var IKM = $.ikm; 
if (IKM==undefined ) { IKM = require('topcam.ikm6')($) }
var GEN = $.gen;
var GUI = $.gui || {};
var Job = $.job || $.job_name;
var JobId = $.job_id;
var db = $.db || IKM.db;
var GenMath = require("topsin.genmath")
var PAR = {}
if ($.par) {
	PAR = $.par
} else if ($.hasOwnProperty('script_parameter')){
	PAR = JSON.parse($.script_parameter);
}
if (mode === "aimdfm") {
	var database = require("topsin.database");
	database.addConnection($.conf.database_conf, "DFM");
	var QDfm = database.query("DFM");
	$.QDfm = QDfm;
	if ($.conf.product_type == "aimdfm") {
		QDfm.updateRow({
			table: "pdm_aimdfm_task",
			data: {
				current_process_title: $.process_title
			},
			where: { id: $.task_id }
		});
	}
}
var Status = 'ok';
var resultData = [];
try {
	var par = PAR;
	PAR.width = 10
	PAR.length = 10
	var default_par = {  // par默认参数?
		step_fliter:"edit",
        layer_type:"inner",
        erf:"Inner (Mils)",
		units: "inch",
		auto_save: "no"
	}
	for(var key in default_par){  // 设置默认属性
		if (!par.hasOwnProperty(key) || par[key] == ""){
			par[key] = default_par[key]
		}
	}
	if(_.isEmpty(Job)){throw "参数Job不存在"}
    var job = Job.toLowerCase()
    // 料号验证
	if(!GEN.isJobExists({job:job})){throw "料号"+job+"不存在"}
	if(!GEN.isJobOpen({job:job})){ GEN.openJob({job:job}) }
	if(mode == "aimdfm"){
        if(GEN.checkInout({job:job,mode:"test"}) != 0){ throw "the job check" }
        GEN.checkInout({job:job,mode:"out"});
    }
    var pu = 150;   // 补参数
	// 脚本开始
	var stepList = GEN.getStepList({job:job})
	if(par.step_fliter != ""){
		stepList = stepList.filter(function(v){
			var step_reg = new RegExp(par.step_fliter)
			return step_reg.test(v)})
	}
	var layer_config = {
		outer: {layer_type:"signal", side:"top|bottom", context:"board", polarity:"positive"},
		inner: {layer_type:"signal", side:"inner", context:"board", polarity:"positive"},
		all: {layer_type:"signal", context:"board", polarity:"positive"},
		power_ground: {layer_type:"power_ground", side:"inner", context:"board", polarity:"negative"},
	} 
	var layer_cfg
	if(par.layer_type != ""){
		layer_cfg = layer_config[par.layer_type]
	}
	var matrix = GEN.getMatrix({job:job})
	var n_layers = Object.keys(matrix).sort(function(a,b){return matrix[a].row - matrix[b].row})
	.filter(function(key){
		var val = matrix[key]
		var flag = true
		if(!layer_cfg){ return false}
		for(var k in layer_cfg){
			var tmp_reg = new RegExp(layer_cfg[k], "ig")
			if(!tmp_reg.test(val[k])){
				flag = false
			}
		}
		return flag
	})
	if(n_layers.length == 0){throw "can not find layer"}
	stepList.forEach(function(step){
		GEN.openStep({job:job, name:step})
		GEN.units({type:par.units})
		GEN.affectedLayer({affected:'no',mode:'all'})
		GEN.clearLayers()
        create_checklist_and_run_analysis({layers:n_layers,aux:1, job:job, step:step}, par);
		n_layers.forEach(function(layer){
            var ms = "ms_1_" + layer
            if(GEN.isLayerExists({job:job, layer:ms})){
                // 过滤铜桥线
                // 先过滤与线路层铜皮未接触的线
                GEN.workLayer({name:ms,display_number:2,clear_before:'yes'})
                GEN.selectByFilter({profile:"in"})
                if(GEN.getSelectCount() > 0){
                    GEN.selClearFeature()
                    GEN.COM("sel_ref_feat,layers="+layer+",use=filter,mode=disjoint,pads_as=shape,f_types=surface,polarity=positive\;negative,include_syms=,exclude_syms=") 
                    if(GEN.getSelectCount() > 0) {GEN.selDelete()}
                    // 分析线路层p2p 得到点 选择include点得线留下来
                    GEN.workLayer({name:layer,display_number:2,clear_before:'yes'})
                    GEN.selectByFilter({feat_types:"pad", include_syms:"r*",profile:"in"})
                    if(GEN.getSelectCount() > 0) {
                        var tmp_layer = layer + "_tmp"
                        if(GEN.isLayerExists({job:job,layer:tmp_layer})){GEN.deleteLayer({job:job,layer:tmp_layer})}
                        GEN.selCopyOther({dest:'layer_name',target_layer:tmp_layer,invert:'no',dx:0,dy:0,size:0})
                        GEN.workLayer({name:tmp_layer,display_number:2,clear_before:'yes'})
                        var tmp_chk = "pad_tmp_chk"
                        if(GEN.isChklistExists({job:job, step:step, chklist:tmp_chk})){
                            GEN.COM("chklist_delete,chklist=" + tmp_chk)
                        }
                        GEN.COM("chklist_create,chklist="+tmp_chk)
                        GEN.COM("chklist_show,chklist="+tmp_chk)
                        GEN.COM("chklist_single,action=valor_analysis_signal,show=yes")
                        GEN.COM("chklist_pclear")
                        GEN.COM("chklist_cupd,chklist=valor_analysis_signal,nact=1,params=((pp_layer="+tmp_layer+")(pp_spacing=200)(pp_r2c=250)(pp_d2c=500)(pp_sliver=4)(pp_min_pad_overlap=5)(pp_tests=Spacing)(pp_selected=All)(pp_check_missing_pads_for_drills=Yes)(pp_use_compensated_rout=Yes)(pp_sm_spacing=Yes)),mode=regular")
                        GEN.COM("chklist_pcopy,chklist=valor_analysis_signal,nact=1")
                        GEN.COM("chklist_ppaste,chklist="+tmp_chk+",row=0")
                        GEN.COM("chklist_close,chklist=valor_analysis_signal,mode=hide")
                        GEN.COM("chklist_cupd,chklist="+tmp_chk+",nact=1,params=((pp_layer="+tmp_layer+")(pp_spacing=200)(pp_r2c=250)(pp_d2c=500)(pp_sliver=4)(pp_min_pad_overlap=5)(pp_tests=Spacing)(pp_selected=All)(pp_check_missing_pads_for_drills=Yes)(pp_use_compensated_rout=Yes)(pp_sm_spacing=Yes)),mode=regular")
                        GEN.COM("chklist_run,chklist="+tmp_chk+",nact=1,area=profile")

                        var meas = GEN.getCheckMeas({job: job,step:step,chklist:tmp_chk,nact:1})
                        if(meas.length > 0 && meas[0] != ""){
                            GEN.COM("chklist_create_lyrs,chklist="+tmp_chk+",severity=3,suffix=");
                            GEN.workLayer({name:ms,display_number:2,clear_before:'yes'})
                            GEN.selRefFeat({layers:"mk_1_" + tmp_layer, use:"filter", mode:"include"})
                            GEN.selReverse()
                            if(GEN.getSelectCount()>0){GEN.selDelete()}
                            GEN.deleteLayer({job:job,layer:["ms_1_" + tmp_layer,"mk_1_" + tmp_layer]})
                        }
                        GEN.deleteLayer({job:job,layer:[tmp_layer]})
                    }

                    // 留下来得线选择符合长度的补铜桥
                    GEN.units({type:"mm"})
                    GEN.workLayer({name:ms,display_number:2,clear_before:'yes'})

                    // 选择长度为 0~(pu/1000) 的 反选删除

                    GEN.COM("filter_set,filter_name=popup,update_popup=yes,slot=line,slot_by=length,min_len=0,max_len=" + pu/1000)
                    GEN.COM("filter_area_strt")
                    GEN.COM("filter_area_end,layer=,filter_name=popup,operation=select,area_type=none,inside_area=no,intersect_area=no")
                    GEN.selReverse()
                    if(GEN.getSelectCount()>0){GEN.selDelete()}
                    
                    var feats = GEN.getFeatures({job:job,step:step,layer:ms,options:"feat_index", units:"mm"})
                    if(feats && feats.length){
                        feats.forEach(function(feat){
                            GEN.COM("sel_net_feat,operation=select,x="+feat.xs+",y="+feat.ys+",use_ffilter=no")
                            if(GEN.getSelectCount() > 1){
                                var tmp_ms = ms + "_tmp";
                                if(GEN.isLayerExists({job:job, layer:tmp_ms})){GEN.deleteLayer({job:job, layer:tmp_ms})}
                                GEN.selMoveOther({target_layer:tmp_ms,invert:'no',dx:0,dy:0,size:0})
                                var tmp_feats = GEN.getFeatures({job:job,step:step,layer:tmp_ms,options:"feat_index", units:"mm"}).map(function(item){
                                    item.length = Math.sqrt((item.xs - item.xe)*(item.xs - item.xe) + ((item.ys - item.ye))*(item.ys - item.ye)) * 1000
                                    return item
                                })
                                tmp_feats.sort(function(a,b){return a.length - b.length})
                                if(tmp_feats[0].length <= pu){
                                    GEN.workLayer({name:tmp_ms,display_number:2,clear_before:'yes'})
                                    GEN.selLayerFeat({layer:tmp_ms, index:tmp_feats[0].index,operation:"select"})
                                    GEN.selMoveOther({target_layer:ms,invert:'no',dx:0,dy:0,size:0})
                                    GEN.workLayer({name:ms,display_number:2,clear_before:'yes'})
                                }
                                if(GEN.isLayerExists({job:job, layer:tmp_ms})){GEN.deleteLayer({job:job, layer:tmp_ms})}
                            } else if(GEN.getSelectCount() == 1) {
                                var length = Math.sqrt((feat.xs - feat.xe)*(feat.xs - feat.xe) + ((feat.ys - feat.ye))*(feat.ys - feat.ye)) * 1000
                                if(length > pu){
                                    GEN.selLayerFeat({layer:ms, index:feat.index,operation:"select"})
                                    GEN.selDelete()
                                }
                            }
                        })
                        var feature = GEN.getFeatures({job:job,step:step,layer:ms,units:"mm"});  // break_sr
                        GEN.createLayer({job:job,layer:layer+ "_copper_b",type:'document',delete_exists:"yes"})
                        GEN.workLayer({name:layer+ "_copper_b",display_number:2,clear_before:'yes'})
                        if(feature && feature.length){
                            feature.forEach(function(feat){
                                if(feat.type == "line"){
                                    var line = {xs:feat["xs"]-0,xe:feat["xe"]-0,ys:feat["ys"]-0,ye:feat["ye"]-0};
                                    var tmpline = getLineParallel(line, (pu*4)/ 2000)
                                    var line1 = tmpline.line1
                                    var line2 = tmpline.line2
                                    var point1 = get_line_center(line1);
                                    var point2 = get_line_center(line2);
                                    var line_new = {xs:point1["x"],ys:point1["y"],xe:point2["x"],ye:point2["y"]};
                                    GEN.addLine({xs:line_new["xs"],ys:line_new["ys"],xe:line_new["xe"],ye:line_new["ye"],symbol:'r'+(pu+20)});
                                }
                            })
                        }
                    }
                    GEN.units({type:par.units})
                }
                GEN.deleteLayer({job:job,layer:["ms_1_" + layer,"mk_1_" + layer]})
            } else {
                GEN.deleteLayer({job:job,layer:["ms_1_" + layer,"mk_1_" + layer]})
            }
		})

		GEN.affectedLayer({mode:'all',affected:'no'});
		GEN.clearLayers();
		GEN.zoomHome();

	})

	// 保存 
	if(/yes/ig.test(par.auto_save)){
		GEN.checkInout({job:job,mode:"out"})  // 结束保存料号 关闭料号
		GEN.saveJob({ job: job });
		GEN.checkInout({job:job,mode:"in"})
		GEN.closeJob({job:job})
	} else {
		GEN.checkInout({job:job,mode:"in"})
	}
    console.log("======================== JTG_OUT_delete_individual_pad_aim end");
    if (mode === "aimdfm") {
		$.QDfm.updateRow({
			table: "pdm_aimdfm_task",
			data: {
				progress: 33.33
			},
			where: { id: $.task_id }
		});
		if (GEN.hasError()) {
			Status = 'error';
			resultData.push({ type: "error", title: "GEN错误!", detail: [{ desc: _.join(GEN.STATUS, "\n") }] });
			return {
				status: Status,
				result_data: resultData
			};
		} else {
			resultData.push({ type: "info", title: "操作完成, 请注意检查!" });
			return {
				status: Status,
				result_data: resultData
			};
		}
	}else {
		return "Done"
	}
} catch (e) {
	IKM.msg(_.join(GEN.STATUS, "\n"))
	IKM.msg(e)
    Status = 'error';
    resultData.push({type: "error", title: "脚本执行出错!", detail: [{desc: _.toString(e)}]});
    return (mode === "aimdfm") ? {status: Status, result_data: resultData} : "Error";
}

function create_checklist_and_run_analysis(obj, par){
	var job = obj.job;
	var step = obj.step;
	var layers = obj.layers;
	var num = par["width"];
	var nact = 1;
	var checklist = 'tmp_signal_analysis';
	var params = {}, items = []
	params["pp_layer"] = '.affected';
	params["pp_tests"] = 'Bottleneck';
	params["pp_selected"] = 'All';
	items.push({
		name:'tmp_signal_check',
		nact:nact,
		action:'valor_analysis_signal',
		erf:par.erf,
		mode:'regular',
		params:params,
	})
	if(GEN.isChklistExists({job:job,step:step,chklist:checklist})){
		GEN.COM("chklist_delete,chklist="+checklist)
	}
	GEN.createChklist({chklist:checklist,items:items});
	GEN.affectedLayer({affected:'yes',layer:layers,clear_before:'yes'});
	GEN.COM('chklist_run',{chklist:checklist,nact:nact,area:'profile'});
	GEN.chklistErfRange({
		job:job,step:step,chklist:checklist,nact:nact,erf:par.erf,default_range:[0,0,0.1],
		range:{
			conductor_width : [num,num+1,num+2],
		}
	});
	if (obj["aux"] == 1) {
		GEN.COM("chklist_create_lyrs,chklist="+checklist+",severity=0,suffix=");
	}
	else {
		GEN.chklistShow({chklist:checklist});
		GEN.COM("chklist_res_show,chklist="+checklist+",nact="+nact+",x=0,y=0,w=0,h=0");
	}
}

function get_line_center(line){
	var xs = line.xs
	var ys = line.ys
	var xe = line.xe
	var ye = line.ye
	return {x:(xs+xe)/2,y:(ys+ye)/2}
}

function getLineParallel(line,length){
    var xs = line.xs
    var ys = line.ys
    var xe = line.xe
	var ye = line.ye
	var linelength = Math.sqrt((xe-xs)*(xe-xs) + (ye-ys)*(ye-ys)) 
	var ylengthq = Math.abs(xe - xs) / linelength * length
	var xlengthq = Math.abs(ye - ys) / linelength * length
	if((xe-xs)*(ye-ys) > 0){
		return {
			line1: {
				xs: xs + xlengthq,
				xe: xe + xlengthq,
				ys: ys - ylengthq,
				ye: ye - ylengthq,
			},
			line2: {
				xs: xs - xlengthq,
				xe: xe - xlengthq,
				ys: ys + ylengthq,
				ye: ye + ylengthq,
			}
		}
	} else if (ye == ys) {
		return {
			line1: {
				xs: xs,
				xe: xe,
				ys: ys - length,
				ye: ye - length,
			},
			line2: {
				xs: xs,
				xe: xe,
				ys: ys + length,
				ye: ye + length,
			}
		}
	} else if (xe == xs) {
		return {
			line1: {
				xs: xs- length,
				xe: xe- length,
				ys: ys ,
				ye: ye ,
			},
			line2: {
				xs: xs +length,
				xe: xe +length,
				ys: ys,
				ye: ye,
			}
		}
	} else {
		return {
			line1: {
				xs: xs + xlengthq,
				xe: xe + xlengthq,
				ys: ys + ylengthq,
				ye: ye + ylengthq,
			},
			line2: {
				xs: xs - xlengthq,
				xe: xe - xlengthq,
				ys: ys - ylengthq,
				ye: ye - ylengthq,
			}
		}
	}
};