=head
 NAME: 
 DESCRIPTION: Signal线路挑选线性铜
 PARAMETER:
	[
		{
			name : 'step_filter',
			type : 'LineEdit',
			title : 'step过滤',
			pack : {row:0,column:1},
			property:{tool_tip:'选择step时候的过滤器'},
		},
		{
			name : 'line_number_min',
			type : 'LineEdit',
			title : 'line转铜最小数量',
			pack : {row:0,column:1},
			property:{tool_tip:'line转铜最小数量'},
		},
		{
			name : 'bak_layer_suf',
			type : 'LineEdit',
			title : '备份层后缀',
			pack : {row:0,column:1},
			property:{tool_tip:'去铜丝参数'},
		}
	]
 VERSION_HISTORY:
	V1.00 2020-11-1 Super
	   1.新版本
 HELP:
	<html><body bgcolor="#DDECFE">
		<font size="3" color="#003DB2"><p>功能简介</p></font>
		  <p> DFM优化 </p>
		  <br>
		<font size="3" color="#003DB2"><p>参数配置</p></font>
		<font color="#008000"><p> ● 无</p></font>
		<font size="3" color="#003DB2"><p>注意事项</p></font>
		  <p> ● 无 </p>
		  <br>
	</body></html>
  
=cut

use strict;
use utf8;
use Data::Dump 'dump';
my ($Job,$Step)=($JOB,undef);
my $Report = 'done';
my @work_layers;

$PAR->{line_number_min} = $PAR->{line_number_min} > 0 ? $PAR->{line_number_min} : 'max';#line转铜最小数量
$PAR->{bak_layer_suf} = $PAR->{bak_layer_suf} ? $PAR->{bak_layer_suf} : '++-bak-suface++';

try {
	###检查Genesis料号是否存在并打开
	show_loading("检查${Job}是否存在..",0,position=>'n');
	if (! $GEN->isJobExists(job=>$Job) ){
        $GUI->msgbox(-icon=>'error',-text=>"料号 $Job 在Genesis中不存在, 请检查!");
        return 'Error';
    }

	update_loading("正在打开料号 ${Job} ...",0,position=>'n');
	$GEN->openJob(job=>$Job) unless ($GEN->isJobOpen(job=>$Job));

	my @steps =  $GEN->getStepList(job=>$Job);
	if ( @steps == 0 ) {
		$GUI->msgbox(-icon=>'error',-text=>'在料号中没有Step存在,你将退出!');
		return 'Error';
	}
	elsif (@steps != 1){
		my $srep_filter = $PAR->{step_filter} ? $PAR->{step_filter} : '.*';
        my @tmp_steps = grep(/$srep_filter/,@steps);
		if ( @tmp_steps == 0 ) {
			$GUI->msgbox(-icon=>'error',-text=>'在料号中没有过滤器中的step存在,你将退出!');
			return 'Error';
		}
        elsif ( @tmp_steps == 1 ) {
            $Step = $tmp_steps[0];
        }
        else {
            $Step = $GUI->select_step(-title=>'请选择工作Step',
                                      -steplist=>\@tmp_steps,
                                      -selectmode=>'single');
            return 'Cancel' unless ($Step);            
        }
	}
    else {
        $Step = $steps[0];
    }

	##
	update_loading("过滤层别...",0,position=>'n');
	@work_layers = get_work_layer();
	return 'Cancel' if grep /^Cancel$/,@work_layers;

	###打开step
	$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();

	update_loading("挑选铜皮中...",0,position=>'n');

	$GEN->COM("disp_off");
	foreach my $layer (@work_layers){
		my @feat = $GEN->getFeatures(job=>$Job,step=>$Step,layer=>$layer,options=>'break_sr');
		next unless @feat;
		my %line_info;
		foreach my $tmp (@feat){
			if($tmp->{type} eq 'line' or $tmp->{type} eq 'arc'){
				++$line_info{$tmp->{symbol}};
			}
		}
		next unless keys %line_info;
		my @tmp = sort {$line_info{$b} <=> $line_info{$a}} keys %line_info;
		#创建铜皮层
		my $line_suface = 'tl++tmp+line+suf+++';
		my $line_chek = 'tl++check+line++type++';
		$GEN->createLayer(job=>$Job,layer=>$line_suface,context=>'misc',type=>'document',delete_exists=>'yes');
		$GEN->createLayer(job=>$Job,layer=>$line_chek,context=>'misc',type=>'document',delete_exists=>'yes');
		#备份层
		my $bak_layer = $layer.$PAR->{bak_layer_suf};
		$GEN->createLayer(job=>$Job,layer=>$bak_layer,context=>'misc',type=>'document',delete_exists=>'yes');
		$GEN->affectedLayer(affected=>'yes',layer=>$layer,clear_before=>'yes');
		$GEN->selCopyOther(target_layer=>$bak_layer,invert=>'no');

		if($PAR->{line_number_min} eq 'max'){
			select_line_suface(symbol_data=>$tmp[0],layer=>$layer,surface=>$line_suface,line_check=>$line_chek);
		}else{
			foreach my $data (@tmp){
				next if $line_info{$data} < $PAR->{line_number_min};
				select_line_suface(symbol_data=>$data,layer=>$layer,surface=>$line_suface,line_check=>$line_chek);
			}
		}

		if(! $GEN->isLayerEmpty(job=>$Job,step=>$Step,layer=>$line_chek)){
			update_loading("请确认 $line_chek 层挑选的线是否全部为线路层走线,请将需要转suface的走线选中...",0,position=>'n');
			$GEN->COM("disp_on");
			$GEN->clearLayers();
			$GEN->affectedLayer( mode=>'all',affected=>'no' );
			$GEN->workLayer(name=>$line_chek,display_number=>1,clear_before=>'yes');
			$GEN->displayLayer(name=>$line_suface,number=>2);
			my $ans = $GEN->PAUSE("Please check line type!");
			unless (defined $ans and $ans eq 'OK' ) {
				return 'Cancel';
			}else{
				$GEN->COM("disp_off");
				$GEN->selMoveOther(target_layer=>$line_suface,invert=>'no') if ( $GEN->getSelectCount() > 0 );
				$GEN->selMoveOther(target_layer=>$layer,invert=>'no');
				$GEN->clearLayers();
				$GEN->deleteLayer(job=>$Job,layer=>[$line_chek]);
			}
		}else{
			$GEN->deleteLayer(job=>$Job,layer=>[$line_chek]);
		}


		if(! $GEN->isLayerEmpty(job=>$Job,step=>$Step,layer=>$line_suface)){
			update_loading("请仔细检查 $line_suface 层挑选的线是否正确...",0,position=>'n');
			$GEN->COM("disp_on");
			$GEN->clearLayers();
			$GEN->affectedLayer( mode=>'all',affected=>'no' );
			$GEN->workLayer(name=>$line_suface,display_number=>1,clear_before=>'yes');
			$GEN->displayLayer(name=>$layer,number=>2);
			my $ans = $GEN->PAUSE("Please check !");
			unless (defined $ans and $ans eq 'OK' ) {
				return 'Cancel';
			}else{
				$GEN->COM("disp_off");
				$GEN->selContourize();
				$GEN->selMoveOther(target_layer=>$layer,invert=>'no');
				# $GEN->affectedLayer(affected=>'yes',layer=>$layer,clear_before=>'yes');
				# $GEN->COM('sel_drawn',type=>'mixed',therm_analyze=>'yes');
				# $GEN->selContourize() if ( $GEN->getSelectCount() > 0 );
				$GEN->clearLayers();
				$GEN->deleteLayer(job=>$Job,layer=>[$line_suface]);
			}
		}else{
			$GEN->deleteLayer(job=>$Job,layer=>[$line_suface]);
			$GEN->copyLayer(source_job=>$Job,source_step=>$Step,source_layer=>$bak_layer,dest_layer=>$layer,mode=>'replace',invert=>'no') ;
		}
	}

	$GUI->msgbox(-icon=>'info',-text=>'脚本运行完成请仔细检查!');

    ###output and return status, if genesis error, it will output genesis error command
	unless ($GEN->{STATUS}){
		return $Report;
	}
	else{
		$GUI->msgbox(-icon=>'error',-text=>join("\n",@{$GEN->{STATUS}}));
		addFlowNotes(-notes=>"   Genesis Error:\n ".join("\n   ",@{$GEN->{STATUS}}));
		return 'Error';
	}
}

catch Error::Simple with {
	my $error = shift;
	$GUI->msgbox(-icon=>'error',-text=>$error);
	return 'Error';
}

finally{
	$GEN->clearLayers();
	$GEN->affectedLayer( mode=>'all',affected=>'no' );
	$GEN->COM("disp_on");
};



=head
	选择线路层
=cut
sub get_work_layer{	
	# 获取工作层
	my %matrix = $GEN->getMatrix(job=>$Job,type=>'hash');
	foreach my $layer (sort {$matrix{$a}{row} <=> $matrix{$b}{row}}  keys %matrix) {
		if(defined($matrix{$layer}{context}) and $matrix{$layer}{context} eq 'board' ){
			if(defined($matrix{$layer}{layer_type}) and $matrix{$layer}{layer_type} eq 'signal' ){
				push @work_layers,$layer;
			}			
		}
	}	
	
	my %tmp_matrix;
	foreach my $layer (@work_layers) {
		$tmp_matrix{$layer} = $matrix{$layer};
	}	
	
	if (@work_layers > 1) {
		@work_layers = $GUI->select_layer(
			-title=>'请选择工作层别',
			-layermatrix=>\%tmp_matrix,
			-selectmode => 'multiple');#single
		return 'Cancel' unless(@work_layers);
	}
	else {
		@work_layers = @work_layers;
	}
	return @work_layers;
}

=head
	挑选线性铜皮 symbol_data=>,layer=>,surface=>
=cut
sub select_line_suface
{
	my %par = @_;
	$GEN->affectedLayer(affected=>'yes',layer=>$par{layer},clear_before=>'yes');
	#挑选最多D码的线
	my $line_tmp = '++-+tl+tmp++line';
	$GEN->createLayer(job=>$Job,layer=>$line_tmp,context=>'misc',type=>'document',delete_exists=>'yes');
	$GEN->selectByFilter(feat_types=>'line\;arc',polarity=>'positive',include_syms=>$par{symbol_data},profile=>'all');
	$GEN->selMoveOther(target_layer=>$line_tmp,invert=>'no') if ( $GEN->getSelectCount() > 0 );

	#挑选PAD
	my $pad_tmp = '++-+tl+tmp++pad';
	$GEN->createLayer(job=>$Job,layer=>$pad_tmp,context=>'misc',type=>'document',delete_exists=>'yes');
	$GEN->selectByFilter(feat_types=>'pad',polarity=>'positive',profile=>'all');
	$GEN->selCopyOther(target_layer=>$pad_tmp,invert=>'no',size=>0);
	#删除cover的pad
	my $line_tmp2 = '++-+tl+tmp++line2';
	$GEN->createLayer(job=>$Job,layer=>$line_tmp2,context=>'misc',type=>'document',delete_exists=>'yes');
	$GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes');
	$GEN->selCopyOther(target_layer=>$line_tmp2,invert=>'no');
	$GEN->affectedLayer(affected=>'yes',layer=>$line_tmp2,clear_before=>'yes');
	$GEN->selContourize();
	$GEN->affectedLayer(affected=>'yes',layer=>$pad_tmp,clear_before=>'yes');
	$GEN->selRefFeat(layers=>$line_tmp2,use=>'filter',mode=>'cover');
	$GEN->selDelete() if ( $GEN->getSelectCount() > 0 );
	$GEN->COM('truncate_layer', layer =>$line_tmp2);

	#挑选与pad连接的线
	$GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes');
	$GEN->selRefFeat(layers=>$pad_tmp,use=>'filter',mode=>'touch');
	my $touch_pad_line = '++-+touch++pad++line';
	if ( $GEN->getSelectCount() > 0 ){
		$GEN->createLayer(job=>$Job,layer=>$touch_pad_line,context=>'misc',type=>'document',delete_exists=>'yes');
		$GEN->selMoveOther(target_layer=>$touch_pad_line,invert=>'no');
	}

	#挑选单独的线移回工作层
	$GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes');
	$GEN->selCopyOther(target_layer=>$line_tmp2,invert=>'no');
	$GEN->affectedLayer(affected=>'yes',layer=>$line_tmp2,clear_before=>'yes');
	$GEN->selContourize();
	my ($size) = $par{symbol_data} =~ /r(.*)/;
	$GEN->COM('sel_resize',size=>-($size+0.05),corner_ctl=>'no');
	$GEN->COM(" sel_clean_surface,accuracy=0.25,clean_size=3,clean_mode=x_and_y,max_fold_len=0");
	$GEN->COM('sel_resize',size=>$size+0.05,corner_ctl=>'no');
	$GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes');
	$GEN->selRefFeat(layers=>$line_tmp2,use=>'filter',mode=>'disjoint');
	$GEN->selMoveOther(target_layer=>$par{layer},invert=>'no') if ( $GEN->getSelectCount() > 0 );

	if($GEN->isLayerExists(job=>$Job,layer=>$touch_pad_line)){
		$GEN->affectedLayer(affected=>'yes',layer=>$touch_pad_line,clear_before=>'yes');
		my $tmp_data = '+++-touch+pad+line+check';
		$GEN->createLayer(job=>$Job,layer=>$tmp_data,context=>'misc',type=>'document',delete_exists=>'yes');
		$GEN->selCopyOther(target_layer=>$tmp_data,invert=>'no',size=>0);
		$GEN->selContourize();
		#不与铜皮相连与PAD相连的移回线路层
		$GEN->selRefFeat(layers=>$line_tmp,use=>'filter',mode=>'disjoint');
		if ( $GEN->getSelectCount() > 0 ){
			my $tmp_layer = '++++-tl++line+touch--+';
			$GEN->createLayer(job=>$Job,layer=>$tmp_layer,context=>'misc',type=>'document',delete_exists=>'yes');
			$GEN->selMoveOther(target_layer=>$tmp_layer,invert=>'no');
			$GEN->affectedLayer(affected=>'yes',layer=>$tmp_data,clear_before=>'yes');
			$GEN->selRefFeat(layers=>$tmp_layer,use=>'filter',mode=>'touch');
			$GEN->selMoveOther(target_layer=>$par{layer},invert=>'no');
			$GEN->deleteLayer(job=>$Job,layer=>[$tmp_layer]);
		}
		$GEN->deleteLayer(job=>$Job,layer=>[$touch_pad_line]);

		#与铜皮和PAD相连
		my $pad_tmp2 = '++pad+++tl++tmp';
		$GEN->affectedLayer(affected=>'yes',layer=>$pad_tmp,clear_before=>'yes');
		$GEN->selRefFeat(layers=>$tmp_data,use=>'filter',mode=>'touch');
		if ( $GEN->getSelectCount() > 0 ){
			$GEN->createLayer(job=>$Job,layer=>$pad_tmp2,context=>'misc',type=>'document',delete_exists=>'yes');
			$GEN->selMoveOther(target_layer=>$pad_tmp2,invert=>'no');
			$GEN->COM('truncate_layer', layer =>$pad_tmp);
			my ($size) = $par{symbol_data} =~ /r(.*)/;
			my @feat = $GEN->getFeatures(job=>$Job,step=>$Step,layer=>$pad_tmp2);
			my $idex = 1;
			foreach my $data (@feat){
				my $pad_size;
				if ($data->{symbol} =~ /^s(\d.*)/) {
					$pad_size = $1;
				}elsif($data->{symbol} =~ /^r(\d.*)/){
					$pad_size = $1;
				}elsif($data->{symbol} =~ /^rect(\d.*)x(\d.*)/){
					$pad_size = $1 > $2 ? $2 : $1;
				}elsif($data->{symbol} =~ /^oval(\d.*)x(\d.*)/){
					$pad_size = $1 > $2 ? $2 : $1;
				}
				$GEN->affectedLayer(affected=>'yes',layer=>$pad_tmp2,clear_before=>'yes');
				$GEN->COM('sel_layer_feat',operation=>'select',layer=>$pad_tmp2,index=>$idex);
				$GEN->selMoveOther(target_layer=>$pad_tmp,invert=>'no',dx=>0,dy=>0,size=>0);
				$GEN->affectedLayer(affected=>'yes',layer=>$tmp_data,clear_before=>'yes');
				$GEN->selRefFeat(layers=>$pad_tmp,use=>'filter',mode=>'touch');
				my $number = $GEN->getSelectCount();
				if($number > 0){
					if($number > 4){
						if($number*$size / $pad_size > 0.5 ){
							$GEN->selMoveOther(target_layer=>$line_tmp,invert=>'no');
						}else{
							$GEN->selMoveOther(target_layer=>$par{line_check},invert=>'no');
						}
					}else{
						#4根以下算单根线的宽度
						if($size / $pad_size > 0.5 ){
							$GEN->selMoveOther(target_layer=>$line_tmp,invert=>'no');
						}else{
							$GEN->selMoveOther(target_layer=>$par{line_check},invert=>'no');
						}
					}
				}
				$idex++;
			}
			$GEN->deleteLayer(job=>$Job,layer=>[$pad_tmp2]);
		}
		$GEN->deleteLayer(job=>$Job,layer=>[$tmp_data]);
	}
	$GEN->deleteLayer(job=>$Job,layer=>[$pad_tmp,$line_tmp2]);
	$GEN->affectedLayer(affected=>'yes',layer=>$line_tmp,clear_before=>'yes');
	if($GEN->isLayerExists(job=>$Job,layer=>$par{surface})){
		$GEN->selMoveOther(target_layer=>$par{surface},invert=>'no');
		$GEN->deleteLayer(job=>$Job,layer=>[$line_tmp]);
	}
}