/*
NAME: 
DESCRIPTION: 原稿拼底片;
PARAMETER:
    [
		{
			name : 'out_line',
			title : '外形层',
			type : 'LineEdit',
			property : {tool_tip : '定原稿拼片的step,如未设定，默认为org'},
		},
		{
			name : 'step',
			title : 'Org step',
			type : 'LineEdit',
			property : {tool_tip : '定原稿拼片的step,如未设定，默认为org'},
		},
		{
			name : 'job_suffix',
			title : '料号后缀',
			type : 'LineEdit',
			property : {tool_tip : '定原稿拼片的料号后缀,如未设定，默认为-org'},
		},
		{
			name : 'path',
			title : '输出路径',
			type : 'LineEdit',
			property : {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-09-01 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> step信息 </p>
		<br>
		<font size="3" color="#003DB2"><p>注意事项</p></font>
		<p> 无 </p>
		<br>
	</body></html>	
*/
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
console.log("==============================>template");
// 引入模块 包
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 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 } });
	}
}
require("topsin.genmath")
var genMath = new GenMath();
var gui = new NewGUI(GUI);
var Status = 'ok';
var resultData = [];
var par = PAR;
var default_par = {
    out_line:"out",
    step:"step",
    job_suffix:"-org",
    path:"C:/Users/Administrator/Desktop/jobs/demo",
	auto_save: "No",
	units:"mm"
}
for(var key in default_par){ if (!par.hasOwnProperty(key) || par[key] == ""){ par[key] = default_par[key] }}
var job = Job;
var Step;
var film_size = ['20x24','22x26','24x28'];
var film_tol_number = 0;  // 总的底片数量 
var sold_mask_layer = [];  // 阻焊层
var cust_code = "",serial="";
if(/^(?:[a-z0-9]{2})([a-z0-9]{2})(?:[a-z0-9])(?:[a-z0-9])(?:[a-z0-9])([a-z0-9]{3})(?:(?:[a-z0-9])(?:[a-z0-9])(?:[a-z0-9])|sys)(?:\-s)?/i.test(job)){
	cust_code = RegExp.$1;
	serial = RegExp.$2;
} 
par.film_name = cust_code + serial + '-org';
try {
	if(_.isEmpty(job)){throw "参数job不存在"} else { job = job.toLowerCase() }
	if(!GEN.isJobExists({job:job})){throw "料号"+job+"不存在"}
	
	var gotoFlag = false;
	Job = job + par.job_suffix;
	// 检查拼片料号是否存在
	var films=[],tmp_matrix={};
	
	if (GEN.isJobExists({job:Job}) ){
		var matrix = GEN.getMatrix({job:Job});
		// my $customer_code = $IKM->select_value(-sql =>"select c.name from job as j left join public_customer as c on j.customer_id = c.id where j.id = $JOB_ID");
		Object.keys(matrix).forEach(function(layer){
			var tmp_reg = new RegExp(par.film_name)
			if( tmp_reg.test(layer) ){
				films.push(layer);
				tmp_matrix[layer] = matrix[layer];
			}
		})
		
		if( films.length ){
			if( GUI.confirm("料号"+Job+"在Genesis中已经存在,且已存在原稿拼片层，是否直接输出？",["yes", "no"], "question") == 'yes' ){
				if( films.length > 1){
					films = GUI.selectLayer({title:'请选择输出的原稿拼片层',
								layermatrix:tmp_matrix,
								layertype: "films", // default type of layertypelist
								layertypelist: [
									{name: "films", display_name: "films", filter: function(x) { 
										return films.indexOf(x["name"]) >= 0 ; }},
								],
								selectmode : 'multiple'}); // single
					if(films.length == 0){throw "canel"}
				}
				gotoFlag = true;
			}
		}else{
			IKM.msg("料号"+Job+"在Genesis中已经存在, 请检查!");
			return 'Cancel';
		}
    }else{
		 GEN.copyJob({source_job:job,dest_job:Job,dest_database:GEN.getJobDbName({job:Job})});
	}

	if(!gotoFlag){

		var stepList = GEN.getStepList({job:job})
		stepList = stepList.filter(function(step){
			var reg = new RegExp(par.step,"ig")
			return reg.test(step)
		})
		Step = stepList[0]
		if ( !GEN.isStepExists({job:Job,step:Step}) ){
			IKM.msg(Step + "不存在，无法拼原稿！");
			throw 'Cancel';
		}
	
		// 获取sold_mask_layer
		sold_mask_layer = getLayer({layer_type:"solder_mask", context: "board"})
		var matrix = GEN.getMatrix({job:Job});
		var _default=[],films=[],tmp_matrix={};
		for (var layer in matrix) {
			if ( GEN.isLayerEmpty( {job:Job,step:Step,layer:layer}) ){
				delete matrix[layer];
				continue;
			}
			var tmp_reg = new RegExp(par.film_name)
			if( tmp_reg.test(layer) ){
				films.push(layer);
				tmp_matrix[layer] = matrix[layer];
				delete matrix[layer];
				continue;
			}
			if( matrix[layer].context == 'board' && matrix[layer].layer_type != 'drill' ){
				_default.push(layer)
			}
			else{
				if(layer == "map" || /^m[12]\-/.test(layer)){
					_default.push(layer);
				}
			}
		}
	
		//
		if( films.length ){
			if( GUI.confirm("已存在原稿拼片层，是否直接输出？"  ["yes", "no"], "question") == 'yes' ){
				if( films.length > 1){
					films = GUI.selectLayer({title:'请选择输出的原稿拼片层',
								layermatrix:tmp_matrix,
								layertype: "films", // default type of layertypelist
								layertypelist: [
									{name: "films", display_name: "films", filter: function(x) { 
										return films.indexOf(x["name"]) >= 0 ; }},
								],
								selectmode : 'multiple'}); // single
					if(films.length == 0){throw "canel"}
				}
				gotoFlag = true;
			}
		}
	}
   
	if(!gotoFlag){
		var tmplayers = GUI.selectLayer({
			title:'请选择需拼片原稿层',
			layermatrix:matrix,
			layertype:"_default",
			layertypelist: [
				{
					name: "_default",
					display_name: "_default",
					filter: function (x) {
						return _default.indexOf(x.name) >=0
					}
				},
				{
					name: "all",
					display_name: "all",
					filter: function (x) {
						return true
					}
				}
			],
			selectmode:'multiple'});
		if(tmplayers.length == 0){throw "cancel"}
		tmplayers = tmplayers.map(function(v){return v.name})
		// 创建拼片的辅助层

		GEN.openStep({job:Job,name:Step});
		GEN.clearLayers();
		GEN.affectedLayer( {mode:'all',affected:'no'} );
		GEN.COM( "sel_options,clear_mode=clear_after,display_mode=all_layers,area_inout=inside,area_select=select,select_mode=standard,area_touching_mode=exclude");
		GEN.units( {type:'inch'} );
		GEN.zoomHome();
		
		if(!GEN.isLayerExists({job:Job,layer:par.out_line})){
			IKM.msg(par.out_line + "层不存在！！");
			throw 'Cancel';
		}
		if(GEN.isLayerEmpty({job:Job,step:Step,layer:par.out_line})){
			IKM.msg(par.out_line + "层为空无法创建profice！！");
			throw 'Cancel';
		}
		

		// 删除板外物 除map层外 2020-07-14 Super
		GEN.affectedLayer({affected:'yes',layer:par.out_line,clear_before:'yes'});
		GEN.COM('sel_reverse');
		if ( GEN.getSelectCount() > 1 ){
			GEN.COM('sel_create_profile');
			GEN.affectedLayer( {mode:'all',affected:'no'} );
		}else{
			GEN.COM('sel_reverse');
			GEN.affectedLayer( {mode:'all',affected:'no'} );
			IKM.msg(par.out_line + "层外形数量太少无法创建profice！！");
			throw 'Cancel';
		}
		tmplayers.forEach(function(layer){
			if(!/^map$/.test(layer)){
				GEN.affectedLayer({affected:'yes',layer:layer,clear_before:'no'});
			}
		})
		GEN.clipArea({layers_mode:'affected_layers',area:'profile',inout:'outside',margin:0,contour_cut:'yes'});
		

		// 复制外形
		GEN.workLayer({name:par.out_line,display_number:1,clear_before:'yes'});
		tmplayers.forEach(function(layer){
			if(!/^map$/.test(layer)){
				GEN.affectedLayer({affected:'yes',layer:layer,clear_before:'no'});
			}
		})
		GEN.selCopyOther({dest:'affected_layers',invert:'no'});
		GEN.clearLayers();
		GEN.affectedLayer( {mode:'all',affected:'no'} );

		// 创建阻焊负片层
		var sold_mask_negative = [];
		if(sold_mask_layer.length > 0){
			sold_mask_layer.forEach(function(layer){
				var tmp_layer = layer+'+1';
				sold_mask_negative.push(tmp_layer)
				var layer_limits = GEN.getLayerLimits({job:Job,step:Step,layer:layer,units:'inch'});
				GEN.createLayer({job:Job,layer:tmp_layer,context:'misc',type:'document',delete_exists:'yes'});
				GEN.affectedLayer({affected:'yes',layer:tmp_layer,clear_before:'yes'});
				GEN.addRectangle({x1:Number(layer_limits.xmin)-0.1,y1:Number(layer_limits.ymin)-0.1,x2:Number(layer_limits.xmax)+0.1,y2:Number(layer_limits.ymax)+0.1});
				GEN.affectedLayer({affected:'yes',layer:layer,clear_before:'yes'});
				GEN.selCopyOther({target_layer:tmp_layer,invert:'yes'});
				GEN.selContourize();
				GEN.affectedLayer({mode:'all',affected:'no'});
			})
		}

		// 总的底片数量
		film_tol_number = tmplayers.length*2 + sold_mask_layer.length;
		
		// 创建辅助层，返回实际需拼片的层
		var tmp_layers = tmplayers;
		tmp_layers = tmp_layers.concat(sold_mask_negative)
		tmplayers = tmplayers.concat(tmp_layers);
		// my @tmp_layers2 = @tmplayers;
		create_tmp_layer({step:Step,layer:tmplayers,matrix:matrix});

		var film_scheme = {};
		var index = 1;
		film_size.forEach(function(filmsize){
			var info = get_repeat_info({step:Step,layer:tmplayers,film_size:filmsize});
			if(!film_scheme[index]){film_scheme[index] = {}}
			film_scheme[index].info = info;
			film_scheme[index].film_count = Object.keys(info).length;
			film_scheme[index].film_size = filmsize;
			index++ ;
		})

		// 选出最优方案
		var best_scheme_index;
		Object.keys(film_scheme).sort().forEach(function(index){
			if(best_scheme_index){
				if(film_scheme[index].film_count < film_scheme[best_scheme_index].film_count){
					best_scheme_index = index;
				}
			}else{
				best_scheme_index = index;
			}
		})
		
		IKM.msg(3)
		film_repeat({step:Step,layer:tmplayers,info:film_scheme[best_scheme_index].info,film_size:film_scheme[best_scheme_index].film_size});
		
		//画profile
		var tmp_fs = film_scheme[best_scheme_index].film_size.split("x")
		var film_width=tmp_fs[0],film_height = tmp_fs[1];
		GEN.COM( 'profile_rect',{x1:0,y1:0,x2:film_width-0.005,y2:film_height-0.005});
		//更改文字序列号
		var change_layers = Object.keys(film_scheme[best_scheme_index].info).sort(function(a,b){
			return film_scheme[best_scheme_index].info[a].num - film_scheme[best_scheme_index].info[b].num
		})
		var number = 1;
		change_layers.forEach(function(layer){
			GEN.affectedLayer({affected:'yes',mode:'single',layer:layer,clear_before:'yes'});
			// GEN.selectByFilter(feat_types:'text',polarity:'positive',profile:'all');
			var tmp_data = GEN.getFeatures({job:Job,step:Step,layer:layer,surface:0,options:'feat_index'});
			// var tmp_data = GEN.getFeatures(job:Job,step:Step,layer:layer,options:'select');
			var txt_data = tmp_data.filter(function(v){return v.type=="text"})
			// $GUI->debug(-text:dump(@txt_data,'---',layer,$Step,$Job));
			txt_data.forEach(function(data){
				GEN.COM('sel_layer_feat',{operation:'select',layer:layer,index:data.index});
				var txt = data.text.split("/")
				var new_text = number+'/'+txt[1];
				GEN.COM( 'sel_change_txt',{
							text:new_text,
							x_size:data.x_size,
							y_size:data.y_size,
							w_factor:data.w_factor,
							polarity:'no_change',
							mirror:'no',
							fontname:data.fontname
				});
				number++;
			})
		})

		// 请检查拼片信息
		var n = 1;
		var lastflag = true
		Object.keys(film_scheme[best_scheme_index].info).sort(function(a,b){
			return film_scheme[best_scheme_index].info[a].num - film_scheme[best_scheme_index].info[b].num
		}).forEach(function(film){
			if(lastflag){
				if( n == 1 ){
					GEN.workLayer({name:film,display_number:1,clear_before:'yes'});
				}
				else{
					GEN.displayLayer({name:film,number:n});
				}
				n++;
			}
			if (n > 4){lastflag = false};
		})
		GEN.PAUSE('Please Check Layer');
	}
	// 
	if(films.length == 0){
		films = Object.keys(film_scheme[best_scheme_index].info).sort(function(a,b){
			return film_scheme[best_scheme_index].info[a].num - film_scheme[best_scheme_index].info[b].num
		})
	}
	//my $film_size = $film_scheme->{$best_scheme_index}{film_size};
	
	//删除多余step和层别
	var steps =  GEN.getStepList({job:Job});
	steps.forEach(function(step){
		if(step != Step){
			GEN.matrixDeleteStep({job:Job,step:step});
		}
	})
	
	var matrix = GEN.getMatrix({job:Job});
	Object.keys(matrix).forEach(function(layer){
		var tmp_reg = new RegExp("^"+par.film_name)
		if(!tmp_reg.test(layer)){
			_deleteLayer({layer:[layer]});
		}
	})
	
	GEN.checkInout({job:Job,mode:'out'});
	// $GUI->debug(-text=>dump($PAR->{path}));
	GEN.saveJob({job:Job});
	GEN.COM('export_job',{job:Job,path:par.path,mode:'tar_gzip',submode:'full',overwrite:'yes'});

	// 保存 
	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"})}
	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 NewGUI (gui) {
    this.msgBox = function(props){ // title  type  content  button
        props = props || {}
        return gui.msgBox(props.title || "title",props.type || "info",props.content || "content",props.button || ["ok", "cancel"]);
    }
    this.selectFromTreeview = gui.selectFromTreeview
    this.selectFile = function(props){ // "choose something", "*", true, "file", "/home/abby/fast_io"
        props = props || {}
        return gui.selectFile(props.title || "choose something",props.filter || "*",props.multiple || false, "file","");
    }
    this.selectSingle = function(props) {
        props = props || {}
        return gui.selectSingle({
            "title": props.title || "select",
            "list": props.list || [],
            "default": props["default"] || "",
            "columns": props.columns || 2,
            "gen":props.gen || GEN
        });
    }
    this.selectMultiple = function(props) {
        props = props || {}
        return gui.selectMultiple({
            "title": props.title || "select",
            "list": props.list || [],
            "defaultvalue": props["defaultvalue"] || [""],
            "defaultsize": props["defaultsize"] || [200, 100],
            "columns": props.columns || 2,
            "gen":props.gen || GEN
        });
    }
    this.selectFromTable = gui.selectFromTable
    this.snapScreen = gui.snapScreen
    this.imageViewer = gui.imageViewer
    this.inputBox = gui.inputBox
    this.showForm = gui.showForm
    this.lockUnlockLayer = function(props){
        props = props || {}
        var tmp = {}
        if (props.matrix) {
            for (var key in props.matrix) {
                var item = props.matrix[key]
                tmp[key] = {
                    row : item.row,
                    name : item.name
                }
            }
        }
        return gui.lockUnlockLayer({
            title: props.title || "lockUnlockLayer",
            layermatrix:props.layermatrix || tmp 
        })
    } 
    this.passwordBox = function(props){
        props = props || {}
        return gui.passwordBox({title:props.title || "password", password:props.password || "1212"})
    } 
    this.selectJobLayer = function (props) {
        props = props || {}
        return gui.selectJobLayer({
            layertypelist: props.layertypelist || [
                {name: "all", display_name: "all", filter: function(x) { return x }},
                {name: "signal", display_name: "signal", filter: function(x) { return x["layer_type"] === "signal"; }},
                {name: "power_ground", display_name: "power_ground", filter: function(x) { return x["layer_type"] === "power_ground"; }},
                {name: "mixed", display_name: "mixed", filter: function(x) { return x["layer_type"] === "mixed"; }},
                {name: "solder_mask", display_name: "solder_mask", filter: function(x) { return x["layer_type"] === "solder_mask"; }},
                {name: "silk_screen", display_name: "silk_screen", filter: function(x) { return x["layer_type"] === "silk_screen"; }},
                {name: "solder_paste", display_name: "solder_paste", filter: function(x) { return x["layer_type"] === "solder_paste"; }},
                {name: "drill", display_name: "drill", filter: function(x) { return x["layer_type"] === "drill"; }},
                {name: "rout", display_name: "rout", filter: function(x) { return x["layer_type"] === "rout"; }},
                {name: "document", display_name: "document", filter: function(x) { return x["layer_type"] === "document"; }}
            ],
            //defaultlayertype: "ha",
            joblist: props.joblist || [],
            defaultJob: props.defaultJob || [], // select by default
            steplist: props.steplist || [],
            // defaultstep: "step3",
            showstep: props.showstep || true,
            selectmode: props.selectmode || "multiple", // single/multiple
            layermatrix: props.layermatrix || {  },
            defaultlayer: props.defaultlayer || []
        })
    }
}

function getLayer(props){
    if(!props){return}
    if(!props.context){props.context = "board"}
    var matrix = GEN.getMatrix({job:job})
    return Object.keys(matrix).reduce(function(a,b){
        var info = matrix[b];
        var ret = true;
        for (var key in props) { if(!Array.isArray(props[key])){props[key] = [props[key]]}
        if(info[key] && props[key].indexOf(info[key]) < 0){ ret = false } }
        if(ret){  a.push(props.res == "info"? info : b) } return a
    },[])
}


function _deleteLayer(layers){
	layers = Array.isArray(layers.layer) ? layers.layer : [layers.layer];
	layers.forEach(function(layer){
		if(GEN.isLayerExists({job:Job,layer:layer})){
			GEN.deleteLayer({job:Job,layer:[layer]})
		}
	})
}

function create_tmp_layer(par){
	var matrix = par.matrix;
	// 先清除原先存在的辅助层
	Object.keys(matrix).forEach(function(layer){
		if(/_$|_tl_angle$/ig.test(layer)){
			GEN.deleteLayer({job:Job,layer:[layer],step:par.step})
		}
	})
	par.layer.forEach(function(layer){
		var tmp_layer = layer+'_';
		var tmp_layer_angle = layer+'_tl_angle';
		GEN.copyLayer({source_job:Job,source_step:par.step,source_layer:layer,dest_layer:tmp_layer,invert:'no',mode:'replace'});
		// 打散层上字串
		GEN.affectedLayer({affected:'yes',layer:[tmp_layer],clear_before:'yes'});
		GEN.selectByFilter({feat_types:'text',profile:'all'});
		if ( GEN.getSelectCount() > 0 ){GEN.COM("sel_break")};
		if(matrix[layer] && matrix[layer].tl_type == 'inner' && matrix[layer].polarity != 'negative' ){
			var layer_limits = GEN.getLayerLimits({job:Job,step:par.step,layer:layer,units:'inch'});
			var tmp = 'pos_to_neg_tl';
			GEN.createLayer({job:Job,layer:tmp,context:'board',type:'document',delete_exists:'yes'});
			GEN.affectedLayer({affected:'yes',layer:[tmp],clear_before:'yes'});
			GEN.addRectangle({x1:Number(layer_limits.xmin)-0.1,y1:Number(layer_limits.ymin)-0.1,x2:Number(layer_limits.xmax)+0.1,y2:Number(layer_limits.ymax)+0.1});
			GEN.affectedLayer({affected:'yes',layer:[tmp_layer],clear_before:'yes'});
			GEN.selCopyOther({target_layer:tmp,invert:'yes'});
			GEN.copyLayer({source_job:Job,source_step:par.step,source_layer:tmp,dest_layer:tmp_layer,invert:'no',mode:'replace'});
			GEN.deleteLayer({job:Job,layer:[tmp],step:par.step});
		}
		// $GUI->debug(dump(matrix[layer].tl_type));
		GEN.copyLayer({source_job:Job,source_step:par.step,source_layer:tmp_layer,dest_layer:tmp_layer_angle,invert:'no',mode:'replace'});
		// 
		GEN.affectedLayer({affected:'yes',layer:[tmp_layer],clear_before:'yes'});
		var layer_limits = GEN.getLayerLimits({job:Job,step:par.step,layer:tmp_layer,units:'inch'});
		GEN.selMove({dx:0-layer_limits.xmin+0.1,dy:0-layer_limits.ymin+0.1});
		// 制作旋转辅助层
		GEN.affectedLayer({affected:'yes',layer:[tmp_layer_angle],clear_before:'yes'});
		GEN.selTransform({mode:'anchor',oper:'rotate',x_anchor:0,y_anchor:0,angle:90});
		layer_limits = GEN.getLayerLimits({job:Job,step:par.step,layer:tmp_layer_angle,units:'inch'});
		GEN.selMove({dx:0-layer_limits.xmin+0.1,dy:0-layer_limits.ymin+0.1});
		// 添加文字标识
		[tmp_layer,tmp_layer_angle].forEach(function(txt_data){
			GEN.affectedLayer({affected:'yes',layer:txt_data,clear_before:'yes'});
			var txt = '1/'+film_tol_number+' '+Job.toUpperCase()+' '+layer.toUpperCase();
			var lay_limt = GEN.getLayerLimits({job:Job,step:par.step,layer:txt_data,units:'inch'});
			Add_Text({x:lay_limt.xmin-0,y:lay_limt.ymin - 0.18,txt:txt,angle:0});
			// GEN.createLayer(job:Job,layer:$txt_data.'+bak',context:'misc',type:'document',delete_exists:'yes');
			// GEN.selCopyOther(target_layer:$txt_data.'+bak',invert:'no');

		})
	})
}

function get_repeat_info(par){
	// 判断不旋转
	var info1 = {};
	var film_size = par.film_size;
	var tmp_film_size = film_size.split("x")
	var film_width = tmp_film_size[0],film_height = tmp_film_size[1];
	var film_org = PAR.film_name+'-'+film_size;
	var film_name=film_org,film_num=0,film_status="old";
	var first_area,last_area={},xstart={},ystart;//第一张底片的范围/上一张底片的范围
	par.layer.forEach(function(layer){
		var tmp_layer = layer+'_';
		film_status = last_area.xmin ? 'old' : 'new' ;
		var layer_limits = GEN.getLayerLimits({job:Job,step:par.step,layer:tmp_layer,units:'inch'});
		layer_limits.xsize = layer_limits.xsize - 0;
		layer_limits.ysize = layer_limits.ysize - 0;
		layer_limits.xmin = layer_limits.xmin - 0;
		layer_limits.ymin = layer_limits.ymin - 0;
		layer_limits.xmax = layer_limits.xmax - 0;
		layer_limits.ymax = layer_limits.ymax - 0;
		var tol_x = (layer_limits.xsize > layer_limits.ysize) ? 0.3 : 0.3;
		var tol_y = (layer_limits.xsize > layer_limits.ysize) ? 0.3 : 0.3;
		// 判断拼入后是否会超出范围
		if( layer_limits.xsize > film_width && layer_limits.ysize > film_height ){
			// xy都超出范围，一片一拼
			film_status = 'new';
		}
		else if( layer_limits.xsize > film_width ){
			film_status = 'new' ;//if ( ($last_area->{ymax}+ layer_limits.ysize) > $film_height );
		}
		else if( layer_limits.ysize > film_height ){
			film_status = 'new' ;//if ( ($last_area->{xmax}+ layer_limits.xsize) > film_width );
		}
		else{
			if ( (last_area.ymax+ layer_limits.ysize) > film_height && (last_area.xmax+ layer_limits.xsize) > film_width ){
				film_status = 'new'
			};
		}

		// 新底片的准备工作
		if( film_status == 'new' ){
			film_name = film_org+'-'+film_num;
			if(!info1[film_name]){info1[film_name] = {}}
			if(!info1[film_name].layers){info1[film_name].layers = []}
			if(!info1[film_name][layer]){info1[film_name][layer] ={shift:{}}}
			info1[film_name].layers.push(layer)
			info1[film_name].num = film_num;
			info1[film_name].type = 'no_angle';

			info1[film_name][layer].shift.x = 0;
			info1[film_name][layer].shift.y = 0;
			xstart.status = 1;
			xstart.shifty = info1[film_name][layer].shift.y;
			first_area = {
				xmin: layer_limits.xmin,
				ymin: layer_limits.ymin,
				xmax: layer_limits.xmax + tol_x,
				ymax: layer_limits.ymax + tol_y,
				xsize: layer_limits.xsize + tol_x,
				ysize: layer_limits.ysize + tol_y
			};
			last_area = first_area;
			film_num++;
		}else{
			// Y方向添加
			if ( (last_area.xsize+ layer_limits.xsize+tol_x) > film_width ){
				//print dump($last_area->{xsize},'--',layer_limits.xsize,'--',film_width),"\n";
				//print dump(@{$info{$film_name}{layers}}),"\n";
				//GEN.PAUSE('tttt++'.$layer);
				if(!info1[film_name]){info1[film_name] = {}}
				if(!info1[film_name].layers){info1[film_name].layers = []}
				if(!info1[film_name][layer]){info1[film_name][layer] ={shift:{}}}
				info1[film_name].layers.push(layer);
				info1[film_name][layer].shift.x = 0;
				info1[film_name][layer].shift.y = last_area.ymax-layer_limits.ymin;
				xstart.status = 1;
				xstart.shifty = info1[film_name][layer].shift.y;
				//$ystart->{status} = 0;$xstart->{shiftx} = undef;
				last_area = {
					xmin: layer_limits.xmin,
					ymin: layer_limits.ymin + info1[film_name][layer].shift.y,
					xmax: layer_limits.xmax + tol_x,
					ymax: info1[film_name][layer].shift.y + layer_limits.ymax + tol_y,
					xsize: layer_limits.xsize + tol_x,
					ysize: layer_limits.ysize + last_area.ysize + tol_y
				};
			}
			// X方向添加
			else{
				if(!info1[film_name]){info1[film_name] = {}}
				if(!info1[film_name].layers){info1[film_name].layers = []}
				if(!info1[film_name][layer]){info1[film_name][layer] ={shift:{}}}
				info1[film_name].layers.push(layer);
				info1[film_name][layer].shift.x = last_area.xmax-layer_limits.xmin;
				info1[film_name][layer].shift.y = xstart.status ? xstart.shifty : last_area.ymax-last_area.xmin;
				//print dump($info{$film_name}{$layer}{shift}{x},'-----',$info{$film_name}{$layer}{shift}{y}),"\n";
				//GEN.PAUSE('ttt++'.$layer);
				xstart.status = 1;
				xstart.shifty = info1[film_name][layer].shift.y;
				var high = (layer_limits.ymax+info1[film_name][layer].shift.y-0+tol_y) > last_area.ymax ? layer_limits.ymax+info1[film_name][layer].shift.y-0+tol_y : last_area.ymax;
				//$ystart->{status} = 1;$ystart->{shiftx} = undef;
				last_area = {
					xmin: layer_limits.xmin + info1[film_name][layer].shift.x,
					ymin: layer_limits.ymin + info1[film_name][layer].shift.y,
					xmax: layer_limits.xmax + info1[film_name][layer].shift.x + tol_x,
					ymax: high,
					xsize: layer_limits.xsize + last_area.xsize + tol_x,
					ysize: layer_limits.ysize + tol_y
				};
			}
		}
	})
	
	// 判断旋转90度
	var info2 = {};
	film_org = PAR.film_name+'-'+film_size;
	film_name = film_org,film_num=0,film_status="old";
	first_area={},last_area={},xstart={},ystart={};//第一张底片的范围/上一张底片的范围
	par.layer.forEach(function(layer){
		var tmp_layer = layer+'_tl_angle';
		film_status = last_area.xmin ? 'old' : 'new' ;
		var layer_limits = GEN.getLayerLimits({job:Job,step:par.step,layer:tmp_layer,units:'inch'});
		layer_limits.xsize = layer_limits.xsize - 0;
		layer_limits.ysize = layer_limits.ysize - 0;
		layer_limits.xmin = layer_limits.xmin - 0;
		layer_limits.ymin = layer_limits.ymin - 0;
		layer_limits.xmax = layer_limits.xmax - 0;
		layer_limits.ymax = layer_limits.ymax - 0;
		var tol_x = (layer_limits.xsize > layer_limits.ysize) ? 0.3 : 0.3;
		var tol_y = (layer_limits.xsize > layer_limits.ysize) ? 0.3 : 0.3;
		//判断拼入后是否会超出范围
		if( layer_limits.xsize > film_width && layer_limits.ysize > film_height ){
			//xy都超出范围，一片一拼
			film_status = 'new';
		}
		else if( layer_limits.xsize > film_width ){
			film_status = 'new' ;//if ( ($last_area->{ymax}+ layer_limits.ysize) > $film_height );
		}
		else if( layer_limits.ysize > film_height ){
			film_status = 'new' ;//if ( ($last_area->{xmax}+ layer_limits.xsize) > film_width );
		}
		else{
			if ( (last_area.ymax+ layer_limits.ysize) > film_height && (last_area.xmax+ layer_limits.xsize) > film_width ){
				film_status = 'new'
			};
		}

		//新底片的准备工作
		if( film_status == 'new' ){
			film_name = film_org+'-'+film_num;
			if(!info2[film_name]){info2[film_name] = {}}
			if(!info2[film_name].layers){info2[film_name].layers = []}
			if(!info2[film_name][layer]){info2[film_name][layer] ={shift:{}}}
			info2[film_name].layers.push(layer)
			info2[film_name].num = film_num;
			info2[film_name].type = 'angle';
			info2[film_name][layer].shift.x = 0;
			info2[film_name][layer].shift.y = 0;
			xstart.status = 1;
			xstart.shifty = info2[film_name][layer].shift.y;
			first_area = {
				xmin: layer_limits.xmin,
				ymin: layer_limits.ymin,
				xmax: layer_limits.xmax + tol_x,
				ymax: layer_limits.ymax + tol_y,
				xsize: layer_limits.xsize + tol_x,
				ysize: layer_limits.ysize + tol_y
			};
			last_area = first_area;
			film_num++;
		}else{
			//Y方向添加
			if ( (last_area.xsize+ layer_limits.xsize+tol_x) > film_width ){
				//print dump($last_area->{xsize},'--',layer_limits.xsize,'--',film_width),"\n";
				//print dump(@{$info{$film_name}{layers}}),"\n";
				//GEN.PAUSE('tttt++'.$layer);
				if(!info2[film_name]){info2[film_name] = {}}
				if(!info2[film_name].layers){info2[film_name].layers = []}
				if(!info2[film_name][layer]){info2[film_name][layer] ={shift:{}}}
				info2[film_name].layers.push(layer);
				info2[film_name][layer].shift.x = 0;
				info2[film_name][layer].shift.y = last_area.ymax-layer_limits.ymin;
				xstart.status = 1;
				xstart.shifty = info2[film_name][layer].shift.y;
				//$ystart->{status} = 0;$xstart->{shiftx} = undef;
				last_area = {
					xmin: layer_limits.xmin,
					ymin: layer_limits.ymin + info2[film_name][layer].shift.y,
					xmax: layer_limits.xmax + tol_x,
					ymax: info2[film_name][layer].shift.y + layer_limits.ymax + tol_y,
					xsize: layer_limits.xsize + tol_x,
					ysize: layer_limits.ysize + last_area.ysize + tol_y
				};
			}
			//#X方向添加
			else{
				if(!info2[film_name]){info2[film_name] = {}}
				if(!info2[film_name].layers){info2[film_name].layers = []}
				if(!info2[film_name][layer]){info2[film_name][layer] ={shift:{}}}
				info2[film_name].layers.push(layer);
				info2[film_name][layer].shift.x = last_area.xmax-layer_limits.xmin;
				info2[film_name][layer].shift.y = xstart.status ? xstart.shifty : last_area.ymax-last_area.xmin;
				//print dump($info{$film_name}{$layer}{shift}{x},'-----',$info{$film_name}{$layer}{shift}{y}),"\n";
				//GEN.PAUSE('ttt++'.$layer);
				xstart.status = 1;
				xstart.shifty = info2[film_name][layer].shift.y;
				var high = (layer_limits.ymax+info2[film_name][layer].shift.y-0+tol_y) > last_area.ymax ? layer_limits.ymax+info2[film_name][layer].shift.y-0+tol_y : last_area.ymax;
				//$ystart->{status} = 1;$ystart->{shiftx} = undef;
				last_area = {
					xmin: layer_limits.xmin + info2[film_name][layer].shift.x,
					ymin: layer_limits.ymin + info2[film_name][layer].shift.y,
					xmax: layer_limits.xmax + info2[film_name][layer].shift.x + tol_x,
					ymax: high,
					xsize: layer_limits.xsize + last_area.xsize + tol_x,
					ysize: layer_limits.ysize + tol_y
				};
			}
		}
	})
	//
	if( Object.keys(info2).length < Object.keys(info1).length){
		return info2;
	}
	else{
		return info1;
	}
}

function film_repeat(par){
	var film_size = par.film_size;
	var tmp_film_size = film_size.split("x")
	var film_width = tmp_film_size[0];
	var film_height = tmp_film_size[1];
	var info = par.info;
	Object.keys(info).sort(function(a,b){return info[a].num - info[b].num}).forEach(function(film){
		if(info[film].layers){
			GEN.createLayer({job:Job,layer:film,conext:'misc',type:'document',delete_exists:'yes'});
			GEN.affectedLayer({affected:'yes',layer:[film],clear_before:'yes'});
			// my $all = scalar(@{$info{$film}{layers}});
			// $GUI->debug(dump($film,  $info{$film}{layers}));
			var n = 1;
			info[film].layers.forEach(function(layer){
				var tmp_layer = info[film].type == 'no_angle' ? layer+'_' : layer+'_tl_angle';
				GEN.affectedLayer({affected:'yes',layer:[tmp_layer],clear_before:'yes'});
				GEN.selMove({dx:info[film][layer].shift.x,dy:info[film][layer].shift.y});
				GEN.copyLayer({source_job:Job,source_step:par.step,source_layer:tmp_layer,dest_layer:film,invert:'no',mode:'append'});
				GEN.selMove({dx:-info[film][layer].shift.x,dy:-info[film][layer].shift.y});
				// GEN.deleteLayer(job:Job,layer:[$layer.'_',$layer.'_tl_angle'],step:par.step);
				n++;
			})
			
			GEN.affectedLayer({affected:'yes',layer:[film],clear_before:'yes'});
			// 移动居中
			var layer_limits = GEN.getLayerLimits({job:Job,step:Step,layer:film,units:'inch'});
			layer_limits.xc = layer_limits.xsize/2-Math.abs(layer_limits.xmin);
			layer_limits.yc = layer_limits.ysize/2-Math.abs(layer_limits.ymin);
			GEN.selMove({dx:film_width/2-layer_limits.xc,dy:film_height/2-layer_limits.yc});
			//
			GEN.addRectangle({x1:0,y1:0,x2:film_width-0.005,y2:film_height-0.005,type:'line',symbol:'r5'});
		}
	})
	
}

// =head
// 	增加文字 Add_Text(x=>,y=>,txt=>,angle=>)
// =cut
function Add_Text(par){
	GEN.COM('add_text',{
		attributes:'no',
		type:'string',
		x:par.x,
		y:par.y,
		text:par.txt,
		x_size:0.15,
		y_size:0.15,
		w_factor:1.6666666269,
		polarity:'positive',
		angle:par.angle,
		mirror:'no',
		fontname:'simple',
		ver:1
	})
}