=head
 NAME: 
 DESCRIPTION: 钻孔输出
 PARAMETER:
	[
		{
			name : 'step_filter',
			title : '工作step',
			type : 'LineEdit',
			property : {tool_tip : '过滤Step名称'},
		},
		{
			name : 'out_dir',
			title : '钻孔输出路径',
			type : 'LineEdit',
			property:{tool_tip:'例如: /output/drill'}
		},
		{
			name : 'cool_spread',
			title : '跳钻距离(um)',
			type : 'LineEdit',
			property:{tool_tip:'例如: 350'}
		},
		{
			name : 'reread_layer',
			type : 'RadioBox',
			title : '回读钻孔程式',
			property : {tool_tip:'未设定,则默认no',
						size_policy:'Expanding,Fixed',item_list:[{name:'yes',text:'Yes'},{name:'no',text:'No'}]},
			pack : {row:1,column:1},
		},
		{
			name : 'is_select_lyr',
			type : 'RadioBox',
			title : '是否选择层别',
			property : {tool_tip:'未设定,则默认no',
						size_policy:'Expanding,Fixed',item_list:[{name:'yes',text:'Yes'},{name:'no',text:'No'}]},
			pack : {row:1,column:1},
		},
		{
			name : 'save_job',
			title : '保存料号',
			type : 'RadioBox',
			property : {
				size_policy:'Expanding,Fixed',
				item_list:[
					{name:'Yes',text:'Yes'},
					{name:'No',text:'No'},
				],
				tool_tip:'脚本结束后自动保存料号,未设定,默认为No'
			},
			pack : {row:1,column:1},
		}
	]
	
 VERSION_HISTORY:
	V1.00 2019-10-22 Super Zhang
	    1.新版本
	V1.1  2020-03-11 Super Zhang
		1.不同尺寸板子增加输出参数
	V1.2  2020-03-12 Super 
		1.修改钻孔输出方式代码
	V1.3  2020-03-23 Super
		1.增加0.549的M97批号孔
	V1.4 2020-3-25 Super
		1.增加web server数据传输
	V1.5 2020-03-27 Super
		1.钻孔输出格式调整为3:3不省零  modal_coords=no
	V1.6 2020-3-30  Super
		1.修改涨缩参数
	V1.7 2020-04-01 Super
		1.钻带表头增加料号和涨缩信息
		2.涨缩中心点按原点移动后的数据从新计算
	V1.8 2020-04-02 Super
		1.涨缩中心按改变原点前的坐标计算
	v1.9 2020-04-04 Super	
		1.angle =  270
	v2.0 2020-04-15 Kurri
		1.增加跳刀参数
	V2.1 2020-04-21 Super
		1.调整T99坐标位置
		2.T02板框监视孔的数据放到T01前面
	V2.2 2020-05-14 Kurri
		1.vpg层也插入M97,${JOB} $S$I
	V2.3 2020-05-15 Kurri
		1.修复涨缩小于1的程序没有正常输出的问题
	V2.31 2020-06-09 Super
		1.扩孔时不再增加G84代码
		2.扩孔钻咀用3.151
		3.修复ncset同名时钻孔无法输出
	V2.32 2020-06-11 Super
		1.输出命名更新
	V2.33 2020-08-18 Super
		1.读取map_info参数2.修复检测孔不是第二把刀的时候检测孔坐标乱刀序,3.双面3.054排序
	V2.34 2020-10-13 Kurri
		1.输出层别选择取消board属性限定
	V2.35 2020-10-16 Kurri
		1.增加程序上传的类型
	V2.36 2020-10-16 Kurri
		1.输出alp和alr时bottom层做mirror
	V2.37 2020-10-21 Kurri
		1.取消测试版本T2.37
	T2.38 2020-10-22 Super
		1.增加短槽拉伸
		2.调整*的M97/M98模式
	T2.39 2020-10-29 Super
		1.更新拉伸规则
		2.706*603的M97/M98位置调整
	V2.38 2020-11-03 Super
		1.测试版本到正式版
		2.取消槽孔角度旋转
		3.输出参数增加single_sr
	V2.39 2020-11-06 Super
		1.输出参数break_sr设置成yes
 HELP:
	<html><body bgcolor="#DDECFE">
		<font size="3" color="#003DB2"><p>功能简介</p></font>
		  <p> 钻孔输出 </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 Encode;
use utf8;
use Data::Dump 'dump';
use File::Copy;
use JSON;
my $json = new JSON;
# my $datum;#增加一个基准点数据
# my @drl_section_data;#监视孔范围数据
# my (@drl_section,$section_tool,$section_number);#监视孔坐标
use_module('TL_GenMath');

my ($Job,$Step)=($JOB,undef);
my $units = 'mm';
# my $url = "http://10.87.66.216:9008/api/TOPMES6_SEC_V6/sec/sec-import_drill_program";
# my $server_data;

# my $map_info = do($GEN->getJobPath(job=>$Job).'/user/PNL_map_info');
# my $new_name = get_new_layer_name("$Job");

##host name为cody电脑名称,本地测试用本地目录
use Sys::Hostname;
my $hostname = hostname;
#$GUI->debug(dump($hostname));
if( $hostname eq 'DESKTOP-010QP68' ){
	$PAR->{out_dir} = 'D:/tmp';
}
if ($hostname eq 'g1kevnzhang'){
	$PAR->{out_dir} = 'D:/tmp';
}

$PAR->{spread} = 2000 unless $PAR->{spread};
$PAR->{reread_layer} = 'no' unless $PAR->{reread_layer};
$PAR->{is_select_lyr} = 'no' unless $PAR->{is_select_lyr};
$PAR->{save_job} = 'No' unless $PAR->{save_job};
$PAR->{cool_spread} = 350 unless $PAR->{cool_spread};#跳孔间距
unless( $PAR->{out_dir} ){
	$GUI->msgbox(-icon=>'warning',-text=>'请在脚本参数中设定钻孔输出路径');
	return 'Cancel';
}
$PAR->{out_dir} = encode('gbk',$PAR->{out_dir});
##
unless( -d $PAR->{out_dir} ){
	$GUI->msgbox(-icon=>'warning',-text=>"$PAR->{out_dir} 脚本参数设定的钻孔输出目录不存在,请确认!");
	return 'Cancel';
}


$PAR->{out_dir} .= '/'.lc($new_name);
mkdir $PAR->{out_dir} unless ( -e $PAR->{out_dir});
my $info;

try {
	show_loading("判断是否选择料号..",0,position=>'n');
	unless( $Job){
		$GUI->msgbox(-icon=>'error',-text=>"请先选择料号后再执行脚本!");
        return 'Cancel';
	}
	
	##检查料号是否存在
	update_loading("检查${Job}是否存在..",0,position=>'n');
	unless ( $GEN->isJobExists(job=>$Job) ){
        $GUI->msgbox(-icon=>'error',-text=>"料号 $Job 不存在,请确认。");
        return 'Cancel';
    }
	
	##
    update_loading("正在打开料号${Job}...",0,position=>'n');
    $GEN->openJob(job=>$Job) unless ($GEN->isJobOpen(job=>$Job));
	##
	update_loading("过滤工作step...",0,position=>'n');
	my $ans = get_work_step();
	return $ans if $ans;

	##选择工作层
	update_loading("过滤层别...",0,position=>'n');
	my @work_layers = select_work_layer();
	return 'Cancel' if $work_layers[0] eq 'Cancel';	
	
	##确认涨缩信息
	my $scale = get_scale_info(layers=>\@work_layers);#-----涨缩值信息确认
	return $scale if $scale eq 'Cancel';
	$PAR->{scale} = $scale;
	
	##
	update_loading("正在打开料号$Step STEP...",0,position=>'n');
	$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=>$units );
	$GEN->zoomHome();
	
	
	$PAR->{profile_limits} = $GEN->getProfileLimits(job=>$Job,step=>$Step,units=>'mm');
	$PAR->{profile_limits}{xc} = $PAR->{profile_limits}{xsize}/2-abs($PAR->{profile_limits}{xmin});
	$PAR->{profile_limits}{yc} = $PAR->{profile_limits}{ysize}/2-abs($PAR->{profile_limits}{ymin});
	$PAR->{sr} = $GEN->getSRLimits(job=>$Job,step=>$Step,units=>'mm');
	
	my $orgDrillToolInfo ;
	
	foreach my $layer (@work_layers) {
		##钻孔输出
		update_loading("$layer 层钻孔正在输出...",0,position=>'n');
		my $output_layer = $Job.'-'.$layer.'-ori';#$Job.'-'.$layer.'-ori'
		my $ans = drill_out(layer=>$layer,output_layer=>$output_layer,scale_x=>$PAR->{scale}{$layer}{x},scale_y=>$PAR->{scale}{$layer}{y});
		return $ans if $ans;
		
		####钻孔程式编辑
		my $new_layer;
		if($PAR->{scale}{$layer}{x} != 1 or $PAR->{scale}{$layer}{y} != 1){
			$new_layer= $new_name.'.'.$layer.('X').($PAR->{scale}{$layer}{x}).('Y').($PAR->{scale}{$layer}{y});
		}else{
			$new_layer= $new_name.'.'.$layer;
		}
		
		my $new_file = $PAR->{out_dir}.'/'.$new_layer;
		update_loading("$layer 层钻孔程式正在编辑...",0,position=>'n');
		$ans = edit_nc_file(layer=>$layer,output_file=>$PAR->{out_dir}.'/'.$output_layer,new_file=>$new_file,x=>$PAR->{scale}{$layer}{x},y=>$PAR->{scale}{$layer}{y});#drl_type=>$drl_type
		return $ans if $ans;
		##删除钻孔输出的临时文件
		unlink $PAR->{out_dir}.'/'.$output_layer;
		##回读钻孔程式
		if( $PAR->{reread_layer} =~ /yes/i){
			update_loading("$layer 层钻孔程式回读中...",0,position=>'n');
			my $new_layer_2 = $new_layer;
			input_drill_program(layer=>$layer,file=>$PAR->{out_dir}.'/'.$new_layer_2,new_layer=>$new_layer);#drl_type=>$drl_type,drl_side=>$drl_side
		}
		#传入web  server数据
		#if($layer =~ /(cdr|vpg|alp|alr|psp)/){
			# update_loading("$layer 层web server数据上传中...",0,position=>'n');
			# open(TMP,$new_file) || die "cannot open $PAR->{out_dir}/$new_layer";
			# my @data = <TMP>;
			# close (TMP);
			# chomp(@data);
			# my $file_data;
			# $file_data = join("\n",@data);			
			# $server_data->{data} = [{
			# 							tooling_type=>"mech_drill",
			# 		 					tooling_name=>$new_layer,
			# 		 					partnumber=>$Job,
			# 		 					tooling_text_data=>$file_data,
			# 						 }];
			# #$GUI->debug(-text=>dump($server_data));
			# my $result = sec_web_services($url,$server_data);
			# if($result){
			# 	$GUI->msgbox(-icon=>'error',-text=>"Web services数据传输错误!");
			# 	return 'Cancel';
			# }
		#}
	}
	
	hide_loading();
	
	##保存料号
	if( $PAR->{save_job} =~ /yes/i ){
		show_loading("$Job 正在保存料号,请稍候...",0,position=>'n');
		$GEN->checkInout(job=>$Job,mode=>'out');
		$GEN->saveJob(job=>$Job);
		hide_loading();
	}
	
    ###output and return status, if genesis error, it will output genesis error command
	unless ($GEN->{STATUS}){
		return 'done';
	}
	else{
		$GUI->msgbox(-icon=>'error',-text=>join("\n",@{$GEN->{STATUS}}));
		return 'Error';
	}
}

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

sub get_work_step {
    my @steps =  $GEN->getStepList(job=>$Job);
	if ( @steps == 0 ) {
		$GUI->msgbox(-icon=>'error',-text=>'在料号中没有Step存在,请确认。');
		return 'Cancel';
	}
	elsif (@steps != 0){
		$PAR->{step_filter} = '.*' unless $PAR->{step_filter};
		my @tmp_steps = grep(/$PAR->{step_filter}/,@steps);
		if ( @tmp_steps == 0 ) {
		   $GUI->msgbox(-icon=>'warning',-text=>'根据脚本参数过滤出来的step不存在,请检查资料或者脚本参数配置!');
		   return 'Cancel';
		}
		elsif (@tmp_steps == 1) {
			$Step = $tmp_steps[0];
		}
        else {
            $Step = $GUI->select_step(-title=>'请选择工作 Step',
                                      -steplist=>[@tmp_steps],
									  -default=>[$tmp_steps[0]],
									  -gen=>$GEN,
                                      -selectmode=>'single');
            return 'Cancel' unless ($Step);            
        }
	}
	return undef;
}

sub select_work_layer {
	my %par = @_;
	my @drill;
	my %matrix = $GEN->getMatrix(job=>$Job,type=>'hash');
	foreach my $layer (sort {$matrix{$a}{row} <=> $matrix{$b}{row}}  keys %matrix) {
		next if $layer =~ /ddr/;
		if(defined($matrix{$layer}{layer_type}) and $matrix{$layer}{layer_type} eq 'drill'){
			push @drill,$layer;
		}
	}
	unless( @drill ){
		$GUI->msgbox(-icon=>'warning',-text=>'资料中无钻孔层,请确认!');
		return 'Cancel';
	}
	if ($PAR->{is_select_lyr} eq 'yes' and scalar @drill > 1) {
		my (%tmp_matrix);
		foreach my $layer (@drill) {
			$tmp_matrix{$layer} = $matrix{$layer};
		}
		@drill = $GUI->select_layer(
			-title=>'请选择输出层别',
			-layermatrix=>\%tmp_matrix,
			-default => ['drl','md','bk','lp'],
			-selectmode => 'multiple');#single
		return 'Cancel' unless(@drill);
	}
	return @drill;
}

sub get_scale_info{
	my %par = @_;
	my (%rows,$n);
	foreach my $layer (@{$par{layers}}){
		$n ++;
		$rows{$layer}{sequence}   = $n;
		$rows{$layer}{layer}      = $layer;
		if($layer eq "md"){
			$rows{$layer}{x} = 1.0004;
			$rows{$layer}{y} = 1.0004;
		}
		else{
			$rows{$layer}{x} = 1.0000;
			$rows{$layer}{y} = 1.0000;			
		}

	}
	my $scale_factor = $GUI->show_tableform (
		-defaultsize=>[380,400],-title => '请确认涨缩值',-rows => \%rows,
		-showcheck => 1,-gen => $GEN,
		-columns => [
			{
				column_name=>'layer',
				label=>'层名称',
				width=>70,
				type=>'label',
			},
			{
				column_name=>'x',
				label=>'X涨缩值',
				width=>130,
				type=>'number',
			},
			{
				column_name=>'y',
				label=>'Y涨缩值',
				width=>130,
				type=>'number',
			},
		],
	);
	return 'Cancel' unless ($scale_factor);
	##
	return $scale_factor;
}

=head
	drillmarge 输出
=cut
sub drill_out
{
	my %par = @_;
	my $nc_set = 'sec-jt';
	
	my @ncsets = $GEN->getNcsetsList(job=>$Job,step=>$Step,layer=>$par{layer});
	if( @ncsets ){
		if (grep (/^($nc_set)$/,@ncsets)) {
			$GEN->COM('ncset_delete',name=>$nc_set);
		}
	}
	
	#钻带涨缩中心点
	my $x_anchor = ($par{scale_x} != 1 or $par{scale_y} != 1) ? $PAR->{profile_limits}{xc} : 0;
	my $y_anchor = ($par{scale_x} != 1 or $par{scale_y} != 1) ? $PAR->{profile_limits}{yc} : 0;
	
	unlink if(-e $PAR->{out_dir}.'/'.$par{output_layer});

	my ($org_x,$org_y,$angle);
	if($PAR->{profile_limits}{ysize} == 603 and $PAR->{profile_limits}{xsize} == 706){
		$org_x = $PAR->{profile_limits}{yc};#- 15
		$org_y = 5;
		$angle = 270;
		$datum->{x} = $PAR->{profile_limits}{xmax} - 5;
		$datum->{y} = $PAR->{profile_limits}{yc};
		$datum->{angle} = 90;
		$datum->{type} = 1;#拼版类型
	}elsif($PAR->{profile_limits}{ysize} == 603 and $PAR->{profile_limits}{xsize} == 606){
		$datum->{x} = $org_x = $PAR->{profile_limits}{xc};#- 5
		$datum->{y} = $org_y = 5;
		$datum->{angle} = $angle = 0;
		$datum->{type} = 0;#拼版类型
	}else{
		$datum->{x} = $org_x = $PAR->{profile_limits}{xc};#- 24
		$datum->{y} = $org_y = 5;
		$datum->{angle} = $angle = 0;
		$datum->{type} = 0;#拼版类型
	}
	
	# 铝片塞防焊和铝片塞树脂程序,bot面时需要mirror
	my $xmirror = 'no';
	my $ymirror = 'no';
	if ($par{layer} =~ /al[pr](\d\d)(\d\d)/) {
		my $start = $1 + 0;
		my $end = $2 + 0;
		if ($start > $end) {
			$xmirror = 'yes';
		}
	}

	#获取@drl_section_data数据
	if($par{layer} =~ /(cdr)/ and $GEN->getLayerCount(job=>$Job) >= 4){
		my @feat = $GEN->getFeatures(job=>$Job,step=>$Step,layer=>'pnl-map',units=>'mm');		
		my @data_tmp = grep($_->{attributes}->[0] =~ /(DRL_SECTION)/,@feat);#获取监视孔坐标
		$section_tool = $map_info->{P}{min_drl} >= 1100 ? 1100 : $map_info->{P}{min_drl};
		@drl_section_data = TL::GenMath->p_trans($datum,$datum->{angle},'no',-$datum->{x},-$datum->{y},@data_tmp);
		# if($datum->{angle} == 90){
		# 	my @data_tmp = TL::GenMath->p_trans($datum,$datum->{angle},'no',0,0,@data_tmp);#坐标选择
		# 	foreach my $data (@data_tmp){
		# 		my $coorder_txt;
		# 		$coorder_txt = change_coode(data=>$data,datum=>$datum);
		# 		$drl_section_data->{$coorder_txt} = 1;
		# 	}
		# }else{
		# 	foreach my $data (@data_tmp){
		# 		my $coorder_txt;
		# 		$coorder_txt = change_coode(data=>{x=>$data->{x},y=>},datum=>$datum);
		# 		$drl_section_data->{$coorder_txt} = 1;
		# 	}
		# }
	}

	my $id = $nc_set;
	$GEN->COM('ncset_units',units=>'mm');
	if($par{layer} =~ /(cdr)/){
		$GEN->affectedLayer(affected=>'yes',layer=>$par{layer},clear_before=>'yes');
		$GEN->COM("adv_filter_reset");
		$GEN->COM("reset_filter_criteria,filter_name=,criteria=all");
		$GEN->selectByFilter(attribute=>[{attribute=>'tl_string',text=>"*LDI_HOLE_Two*"}]);
		$GEN->selectByFilter(attribute=>[{attribute=>'tl_string',text=>"*XRAY_HOLE*"}]);
		$GEN->COM("adv_filter_reset");
		$GEN->COM("reset_filter_criteria,filter_name=,criteria=all");
		$GEN->selChangeSym(symbol=>'r1') if $GEN->getSelectCount();
		$GEN->affectedLayer( mode=>'all',affected=>'no' );
	}
	
	#$GEN->COM('open_sets_manager',test_current=>'no');
	$GEN->COM('nc_create',ncset=>$id,device=>'basic_excellon',lyrs=>$par{layer},thickness=>0);
	$GEN->COM('nc_set_advanced_params',layer=>$par{layer},ncset=>$id);
	$GEN->COM('nc_set_current',job=>$Job,step=>$Step,layer=>$par{layer},ncset=>$id);
	$GEN->COM('nc_set_file_params',single_sr=>'no',output_path=>$PAR->{out_dir},output_name=>$par{output_layer},zeroes=>'none',units=>'mm',tool_units=>'mm',nf1=>3,nf2=>3,decimal=>'no',modal_coords=>'no');
	$GEN->COM('nc_register',angle=>$angle,xoff=>0,yoff=>0,version=>1,xorigin=>$org_x,yorigin=>$org_y,xscale=>$par{scale_x},yscale=>$par{scale_y},xscale_o=>$x_anchor,yscale_o=>$y_anchor,xmirror=>$xmirror,ymirror=>$ymirror);
	$GEN->COM('nc_set_optim',optimize=>'yes',iterations=>5,reduction_percent=>1,cool_spread=>$PAR->{cool_spread},break_sr=>'yes',xspeed=>2540,yspeed=>2540,diag_mode=>'45ort');
	$GEN->COM('nc_cre_output',layer=>$par{layer},ncset=>$id);
	my $profile = $GEN->getProfileLimits(job=>$Job,step=>$Step,units=>'mm');
	$GEN->origin(x=>$profile->{xmin},y=>$profile->{ymin});

	
	if($par{layer} =~ /(cdr)/){
		$GEN->affectedLayer(affected=>'yes',layer=>$par{layer},clear_before=>'yes');
		$GEN->COM("adv_filter_reset");
		$GEN->COM("reset_filter_criteria,filter_name=,criteria=all");
		$GEN->selectByFilter(attribute=>[{attribute=>'tl_string',text=>"*LDI_HOLE_Two*"}]);
		$GEN->selectByFilter(attribute=>[{attribute=>'tl_string',text=>"*XRAY_HOLE*"}]);
		$GEN->COM("adv_filter_reset");
		$GEN->COM("reset_filter_criteria,filter_name=,criteria=all");
		$GEN->selChangeSym(symbol=>'r3054') if $GEN->getSelectCount();
		$GEN->affectedLayer( mode=>'all',affected=>'no');
	}
	
	@ncsets = $GEN->getNcsetsList(job=>$Job,step=>$Step,layer=>$par{layer});
	if( @ncsets ){
		if (grep (/^($nc_set)$/,@ncsets)) {
			$GEN->COM('ncset_delete',name=>$nc_set);
		}
	}

	return undef;
}

sub edit_nc_file{
	my %par = @_;
	open(TMP,"$par{output_file}") || die "cannot open $par{output_file}";
	my @data = <TMP>;
	close (TMP);
	chomp @data;
	#
	my %data = split_program(data=>\@data);
	my $ans = convert_new_program(layer=>$par{layer},new_file=>$par{new_file},data=>\%data,x=>$par{x},y=>$par{y});
	return $ans if $ans;	

	return undef;
}

sub split_program{
	my %par = @_;
	my $ui_info = $par{info};
	my (%info);
	my ($flag,$router_flag) = ('start',undef);
	foreach my $line(@{$par{data}}){
		if( $flag eq 'start' ){
			if( $line eq 'M48' ){
				$flag = 'overhead';
			}
		}
		elsif( $flag eq 'overhead' ){
			if( $line =~ /^T01C/i ){
				$flag = 'head';
			}
		}
		elsif( $flag eq 'head' ){
			if( $line !~ /^T\d+/i ){
				$flag = 'neck';
			}
		}
		elsif( $flag eq 'neck' ){
			if( $line =~ /^T01/i ){
				$flag = 'body';
			}
		}
		elsif( $flag eq 'body' ){
			if( $line =~ /^M30$/i ){
				$flag = 'end';
			}
		}
		##
		if( $flag eq 'overhead' ){
			push @{$info{overhead}},$line;
		}
		elsif( $flag eq 'head' ){
			if($line =~ /^T(\d+)C(.*)/){
				if($2 - $section_tool/1000 < 0.0001){
					$section_number = $1;
				}
			}
			push @{$info{head}},$line;
		}
		elsif( $flag eq 'neck' ){
			push @{$info{neck}},$line;
		}
		elsif( $flag eq 'body' ){
			if( $line =~ /^(T(\d+))$/i ){
				$router_flag = $1;
			}
			if($router_flag){
				my ($num) = $router_flag =~ /^T(\d+)$/;
				$info{body}{$router_flag}{num} = $num;
				#判断孔的范围 2020-04-21
				# if($num - $section_number < 0.001 and $line !~ /^T/){
				# 	my $point = change_coode_to_vale($line);
				# 	my $are_check = 0;
				# 	foreach my $symbol (@drl_section_data){
				# 		my $dist = TL::GenMath->point2sym_dist($point,$symbol);
				# 		if($dist == 0){
				# 			$are_check = 1;
				# 			last;
				# 		}
				# 	}
				# 	if($are_check){
				# 		push @drl_section,$line;
				# 	}else{
				# 		push @{$info{body}{$router_flag}{value}},$line;
				# 	}
				# }else{
					push @{$info{body}{$router_flag}{value}},$line;
				# }
			}
		}
		elsif( $flag eq 'end' ){
			push @{$info{end}},$line;
		}
		##
	}
	if( wantarray ){
		return %info;
	}
	else{
		return \%info;
	}
}

sub convert_new_program{
	my %par = @_;
	##
	open(NEWMYFILE,">$par{new_file}");
	my %data = %{$par{data}};
	
	##0.插入表头
	# if($par{x} != 1 or $par{y} != 1){
	# 	print NEWMYFILE 'M47,'.$Job.' '.'X:'.$par{x}.'  '.'Y:'.$par{y},"\n";
	# }

	##1.头顶(刀径清单之前的)/overhead
	foreach my $line(@{$data{overhead}}){
		print NEWMYFILE $line,"\n";
	}
	##
	##2.程序头(router清单)/head
	my $tool_change = get_tool_change(layer=>$par{layer},data=>$par{data});
	
	#$GUI->debug(dump($tool_change));
	###人工排序一次
	# $tool_change = manual_sort_tool(layer=>$par{layer},data=>$par{data},info=>$tool_change);
	# return $tool_change if $tool_change eq 'Cancel';

	##目前扩孔后没有其它类型的孔 
	my $nibble_suffix = 1;
	my $check_nibble_tool = 0; 
	foreach my $line(@{$data{head}}){
		my ($tool,$suffix) = $line =~ /^(T\d+)C.*$/;
		next unless $tool;
		##刀序顺序使用最新的
		next unless $tool_change->{$tool}{new_tool};
		foreach my $item(values %$tool_change){
			if( $tool eq $item->{new_tool} ){
				if($tool_change->{$item->{new_tool}}{size} > 6.35){
					if(! $check_nibble_tool){
						print NEWMYFILE $tool.'C'.(3.15 + $nibble_suffix/1000),"\n";
						#$nibble_suffix++;
						$check_nibble_tool = 1;
					}
				}else{
					print NEWMYFILE $item->{new_header},"\n";
				}
				$PAR->{tool_num_count} = $item->{new_tool_num} unless ($PAR->{tool_num_count} and $PAR->{tool_num_count} > $item->{new_tool_num});
				#$hole_exit = 1 if $item->{new_header} =~ /503$/;
			}
		}
		
	}
	
	# if($par{layer} =~ /(cdr|vpg|alp|alr|psp)/){
	# 	print NEWMYFILE 'T99C0.549',"\n";
	# }
	
	##3.脖子(程序头和正式T序坐标之间)/neck
	foreach my $line(@{$data{neck}}){
		next if $line =~ /g93/i;
		print NEWMYFILE $line,"\n";
	}
	
	# if(@drl_section_data){
	# 	print NEWMYFILE 'T'.$section_number,"\n";
	# 	foreach my $tmp (@drl_section){
	# 		print NEWMYFILE $tmp,"\n";
	# 	}
	# }

	##4.实际的每把T序/body
	my $nibble_tool_check = 0;
	foreach my $tool (sort{$data{body}{$a}{num}<=>$data{body}{$b}{num}} keys %{$data{body}}){
		##获取对应的新刀径
		my $new_tool;
		my $check_drl_section = 0;
		foreach my $old_tool(keys %$tool_change){
			if( $tool eq $tool_change->{$old_tool}{new_tool} ){
				$new_tool = $old_tool;
			}
		}
		next unless $new_tool;
		foreach my $line(@{$data{body}{$new_tool}{value}}){
			#if( abs($tool_change->{$new_tool}{size} - 3.175) < 0.001 ){
			#	if( $line =~ /^(T\d+)/ ){
			#		print NEWMYFILE '/',$tool,"\n";
			#	}
			#	else{
			#		print NEWMYFILE '/',$line,"\n";
			#	}
			#}
			#else{
				#if( $line =~ /^(T\d+)/ ){
				#	print NEWMYFILE $tool,"\n";
				#}
				#else{
				#	print NEWMYFILE $line,"\n";
				#}
			#}
			if( $tool_change->{$new_tool}{size} > 6.35 ){
			 	if( $line =~ /^(T\d+)/ ){
					if( !$nibble_tool_check ){
						print NEWMYFILE $tool,"\n";
						$nibble_tool_check = 1;
					}
			 	}
			 	else{
			 		print NEWMYFILE $line,"\n";#'G84X'.$tool_change->{$new_tool}{size}
			 	}
			 }
			 else{
				if( $line =~ /^(T\d+)/ ){
					print NEWMYFILE $tool,"\n";
				}
				else{
					if( $line =~ /X.*Y.*G85X.*Y.*/ ){
						my ($tmp1,$tmp2) = $line =~ /(X\-?\d*\.?\d*Y\-?\d*\.?\d*)G85(X\-?\d*\.?\d*Y\-?\d*\.?\d*)/;
						my $slot_star = change_coode_to_vale($tmp1);
						my $slot_end  = change_coode_to_vale($tmp2);
						my $slot_size = $tool_change->{$new_tool}{size};
						my $slot_length = $slot_size + TL::GenMath->line_length({xs=>$slot_star->{x},xe=>$slot_end->{x},ys=>$slot_star->{y},ye=>$slot_end->{y}});
						my $slot_info = ger_short_slot_vale(slot_size=>$slot_size,slot_length=>$slot_length);
						#if($slot_info){
						#	my $angle = $slot_info->{angle};
						#	my $point = TL::GenMath->rotate_point($slot_star,$slot_end,$angle);
						#	my $tmp_data = change_coode(data=>{x=>$point->{x},y=>$point->{y}},datum=>{x=>0,y=>0});
						#	my $tmp_line = $tmp1.'G85'.$tmp_data;
						#	print NEWMYFILE $tmp_line,"\n";
						#}else{
							print NEWMYFILE $line,"\n";
						#}
					}else{
						print NEWMYFILE $line,"\n";
					}
				}
			 }
		}
	}

	#插入M97坐标 'X-214500Y000000'
	if($par{layer} =~ /(cdr|vpg|alp|alr|psp)/){
		my @feat = $GEN->getFeatures(job=>$Job,step=>$Step,layer=>'pnl-map',units=>'mm');
		my @feat_M97 = grep($_->{attributes}->[0] =~ /(DRL_TXT_DRL)/,@feat);
		my $coordinate_txt;
		my $mode;#判断*的位置是横放还是竖放 1 代表横放 2代表竖放
		if($feat_M97[0]->{x} >= $PAR->{sr}{xmin} and $feat_M97[0]->{x} <= $PAR->{sr}{xmax}){
			$mode = 1;
		}else{
			$mode = 2;
		}
		
		
		if($datum->{angle} == 90){
			my @M97_tmp = TL::GenMath->p_trans($datum,$datum->{angle},'no',0,0,({x=>$feat_M97[0]->{x},y=>$feat_M97[0]->{y}}));#返回的是一个数组
			if($mode == 1){
				$coordinate_txt = change_coode(data=>{x=>$M97_tmp[0]->{x} + 2.5 - 0.275,y=>$M97_tmp[0]->{y} - 25 + 0.275},datum=>$datum);
			}else{
				$coordinate_txt = change_coode(data=>{x=>$M97_tmp[0]->{x} - 25 + 0.275,y=>$M97_tmp[0]->{y} - 2.5 + 0.275},datum=>$datum);
			}
		}else{
			if($mode == 1){
				$coordinate_txt = change_coode(data=>{x=>$feat_M97[0]->{x} - 25 + 0.275,y=>$feat_M97[0]->{y} - 2.5 + 0.275},datum=>$datum);
			}else{
				$coordinate_txt = change_coode(data=>{x=>$feat_M97[0]->{x} + 2.5 - 0.275,y=>$feat_M97[0]->{y} - 25 + 0.275},datum=>$datum);
			}
		}
		if($datum->{angle} == 90){
			print NEWMYFILE 'T99',"\n";
			if($mode == 1){
				#$GEN->PAUSE('M98');
				print NEWMYFILE 'M98,'.substr($Job,0,6).' $S$I',"\n";
			}else{
				#$GEN->PAUSE('M97');
				print NEWMYFILE 'M97,'.substr($Job,0,6).' $S$I',"\n";
			}
			print NEWMYFILE $coordinate_txt,"\n";
		}else{
			print NEWMYFILE 'T99',"\n";
			if($mode == 1){
				print NEWMYFILE 'M97,'.substr($Job,0,6).' $S$I',"\n"
			}else{
				print NEWMYFILE 'M98,'.substr($Job,0,6).' $S$I',"\n";
			}
			print NEWMYFILE $coordinate_txt,"\n";
		}
	}

	##5.结束/end
	foreach my $line(@{$data{end}}){
		print NEWMYFILE $line,"\n";
	}
	##
	close (NEWMYFILE);
	return undef;
}

sub get_tool_change{
	my %par = @_;
	my %info;
	my %data = %{$par{data}};
	my $is_laser = $par{is_laser};
	my $row_num = 0;
	
	##
	my (%head,%special,$exist_2500);
	##先判断有无3.054的刀径(排第1)
	foreach my $line(@{$data{head}}){
		my ($tool,$size,$data) = $line =~ /^(T\d+)C(\d*\.?\d{3})(S?.*)$/;
		next unless $tool;
		$head{$tool}{data} = 'C'.$2;
		####
		if( abs($size - 0.001) < 0.0001 ){
			$head{$tool}{data} = 'C3.054';
			$row_num++;
			$info{$tool}{new_tool_num} = $row_num;
			$info{$tool}{new_tool} = 'T'.sprintf("%02s",$row_num);
			$info{$tool}{size} = 3.054;
			$info{$tool}{new_header} = $info{$tool}{new_tool}.$head{$tool}{data};
		}
	}
	
	foreach my $line(@{$data{head}}){
		my ($tool,$size,$data) = $line =~ /^(T\d+)C(\d*\.?\d{3})(.*)$/;
		next unless $tool;
		next if(abs($size - 0.001) < 0.0001);
		$row_num++;
		$info{$tool}{size} = $size;
		$info{$tool}{new_tool_num} = $row_num;
		$info{$tool}{new_tool} = 'T'.sprintf("%02s",$row_num);
		$info{$tool}{new_header} = $info{$tool}{new_tool}.$head{$tool}{data};
	}
	return \%info;
}

sub manual_sort_tool{
	my %par = @_;
	my $data = $par{data};
	my $tool_info = $par{info};
	my @items;
	my ($slot_flag,@slot_size);
	foreach my $num(1..scalar(keys %{$data->{body}})){
		my $tool = 'T'.sprintf("%02s",$num);
		next unless $tool_info->{$tool}{new_tool};
		foreach my $old_tool(sort{$tool_info->{$a}{new_tool_num}<=>$tool_info->{$b}{new_tool_num}} keys %$tool_info){
			if( $tool eq $tool_info->{$old_tool}{new_tool} ){
				my $suffix;
				my $size = $tool_info->{$old_tool}{size};
				push @items,{tool=>$old_tool,size=>$tool_info->{$old_tool}{size} >=  1 ? $tool_info->{$old_tool}{size} : '0'.$tool_info->{$old_tool}{size},suffix=>$suffix};
				last;
			}
		}
	}
	
	update_loading("$par{layer} 层请确认钻刀排列顺序...",0,position=>'n');
	my %form = $GUI->show_form(
		-title => "请确认钻孔刀径顺序",
		-defaultsize => [400,500],
		-columns => 2,
		-items => [
			{
				name => 'table',
				type => 'treeview',
				label => '',
				label_position => 'top',
				expand=>1,
				scrolledwindow=>{},
				property => {
					height_request=>200,
					tl_model_type => 'list',
					enable_grid_lines => 'none',
					tl_mapping =>['tool' => 'Glib::String','size' => 'Glib::String','suffix'=>'Glib::String'],
					tl_columns =>[
						{title=>'原始刀序',visible=>1,resizable=>1,min_width=>80,expand=>1,renders=>[{class=>'Text',property=>{editable=>0,background=>'#FCFBB6',foreground=>'#000000'},text=>'tool'}]},
						{title=>'刀径',visible=>1,resizable=>1,min_width=>80,expand=>1,renders=>[{class=>'Text',property=>{editable=>0,background=>'#FCFBB6',foreground=>'#000000'},text=>'size'}]},
						{title=>'后缀(可编辑)',visible=>1,resizable=>1,min_width=>80,expand=>1,renders=>[{class=>'Text',property=>{editable=>1,background=>'#C5DBF2',foreground=>'#000000'},text=>'suffix'}]},
					],
				},
				value => \@items,
				get_value_func => sub{ my %par = @_;
					my $tvdata = $par{widget}->tl_get_model_data();
					return $tvdata;
				},
				set_value_func => sub{ my %par = @_;
					my $v = $par{value};
					$par{widget}->tl_set_data($v);
					return 0;
				},
				button_position=>'top',
				buttons => [
					{   name=>'top',label=>'置顶',stock=>'gtk-goto-top',
						command=>sub{ my %p = @_;
							my $widget = $p{formpanel}->get_widget('table');
							$widget->set_property(reorderable=>1);
							$widget->tl_sel_moveto_top();
							$widget->set_property(reorderable=>0);
						}
					},
					{   name=>'up',label=>'上移',stock=>'gtk-go-up',
						command=>sub{ my %p = @_;
							my $widget = $p{formpanel}->get_widget('table');
							$widget->set_property(reorderable=>1);
							$widget->tl_sel_move_up();
							$widget->set_property(reorderable=>0);
						}
					},
					{   name=>'down',label=>'下移',stock=>'gtk-go-down',
						command=>sub{ my %p = @_;
							my $widget = $p{formpanel}->get_widget('table');
							$widget->set_property(reorderable=>1);
							$widget->tl_sel_move_down();
							$widget->set_property(reorderable=>0);
						}
					},
					{   name=>'bottom',label=>'置底',stock=>'gtk-goto-bottom',
						command=>sub{ my %p = @_;
							my $widget = $p{formpanel}->get_widget('table');
							$widget->set_property(reorderable=>1);
							$widget->tl_sel_moveto_bottom();
							$widget->set_property(reorderable=>0);
						}
					},
				],
			},
		]
	);
	return 'Cancel' unless %form;
	##将界面确认的结果重新整理一遍
	my %info;
	my @data = @{$form{table}};
	my $row_num;
	foreach my $item(@data){
		$row_num++;
		if( $item->{suffix} =~ /^\(w(\d+)\)$/i || $item->{suffix} =~ /^\(w(\d+)s\d+\)$/i || $item->{suffix} =~ /^\(s(\d+)\)$/i){
			$info{$item->{tool}}{suffix} = $item->{suffix};
			$info{$item->{tool}}{size} = $item->{size};
		}
		elsif($item->{suffix} =~ /^(\d+)$/i ){
			$info{$item->{tool}}{suffix} = $item->{suffix}+0;
			$info{$item->{tool}}{size} = $item->{size};
		}
		else{
			$info{$item->{tool}}{size} = $item->{size};
		}
		$info{$item->{tool}}{new_tool_num} = $row_num;
		$info{$item->{tool}}{new_tool} = 'T'.sprintf("%02s",$row_num);
		if( $item->{suffix} =~ /^\((w|s)(\d+)\)$/i || $item->{suffix} =~ /^\(w(\d+)s(\d+)\)$/i){
			$info{$item->{tool}}{new_header} = $info{$item->{tool}}{new_tool}.'C'.sprintf("%.3f",$info{$item->{tool}}{size}).$item->{suffix};
		}
		else{
			$info{$item->{tool}}{new_header} = $info{$item->{tool}}{new_tool}.'C'.sprintf("%.3f",$info{$item->{tool}}{size});
		}
	}
	##
	return \%info;
}

sub input_drill_program{
	my %par = @_;
	$GEN->COM( "input_manual_reset");
	$GEN->COM( "input_manual_set,path=$par{file},job=$Job,step=$Step,format=Excellon2,data_type=ascii,
				units=mm,coordinates=absolute,zeroes=none,nf1=3,nf2=3,decimal=no,separator=nl,tool_units=mm,layer=$par{new_layer},wheel=,
				wheel_template=,nf_comp=0,multiplier=1,text_line_width=0.0024,signed_coords=no,break_sr=yes,drill_only=no,merge_by_rule=no,threshold=200,resolution=3");
	$GEN->COM( "input_manual,script_path=");
	$GEN->zoomHome();
	return undef;
}

=head
	web server数据传输
=cut
sub  sec_web_services{
	use LWP::UserAgent;     
    use LWP;      
    use HTTP::Headers;    
    use HTTP::Response;
	use Encode;
	use JSON;
	use JSON qw(encode_json); 
	 my $url = shift;
	 my $data = shift;
	 my $json = JSON->new->allow_nonref;
	 my $ua = LWP::UserAgent->new();
     $ua->agent("Mozilla/5.0 (Windows NT 6.1; rv:30.0) Gecko/20100101 Firefox/30.0");
	 my $header = ['Content-Type' => 'application/json; charset=UTF-8'];
	 my $body = encode('utf8', $json->encode($data));
	 my $request = HTTP::Request->new('POST', $url, $header, $body);
	 my $res = $ua->request($request);
	 #$GUI->debug(-text=>dump($res,'-----------------------------------------------------------------',$res->is_success));
	 if ($res->is_success) { 
		return 0;
	 }else{
		return 1;
	 }
}


=head
	3:3 不省零
	坐标转换 data=>{x=>,y=>} datum=>{x=>,y=>}
=cut
sub change_coode
{
	my %par = @_;
	my ($check_x,$check_y);
	$par{data}->{x} = $par{data}->{x} - $par{datum}->{x};
	$par{data}->{y} = $par{data}->{y} - $par{datum}->{y};

	$check_x = $par{data}->{x} > 0 ? '': '-';
	$check_y = $par{data}->{y} > 0 ? '': '-';

	$par{data}->{x} = sprintf("%0.3f",$par{data}->{x});
	$par{data}->{x} = sprintf("%06s",abs($par{data}->{x})*1000);

	$par{data}->{y} = sprintf("%0.3f",$par{data}->{y});
	$par{data}->{y} = sprintf("%06s",abs($par{data}->{y})*1000);

	return 'X'.$check_x.($par{data}->{x}).'Y'.$check_y.($par{data}->{y});
}


=head
	坐标转换成数值
=cut
sub change_coode_to_vale
{
	my $string = shift;
	$string =~ /X(-?\w+)Y(-?\w+)/;
	my $x_data = sprintf("%0.3f",$1/1000);
	my $y_data = sprintf("%0.3f",$2/1000);
	return {x=>$x_data,y=>$y_data};
}


sub _deleteLayer{
    my %par = @_;
    foreach my $layer(@{$par{layer}}){
        $GEN->deleteLayer(layer=>$layer) if ($GEN->isLayerExists(job=>$Job,layer=>$layer));
    }
}


=head
	输出层新命名
=cut
sub  get_new_layer_name
{
		my $job = shift;
		my @tmp = split/\-/,$job;
		splice(@tmp,2,1);
		$tmp[2] =~ s/2//;
		unless($tmp[2]){
			splice(@tmp,2,1);
		}
		my $new = join('-',@tmp);
		return $new;
}

=head
	短槽拉伸值 slot_size=>,slot_length=> 
=cut
sub ger_short_slot_vale
{
	my %par = @_;
	my $info = {
					1.5 =>[
						{size_min=>0.4,size_max=>0.55,length=>0,angle=>0},
						{size_min=>0.6,size_max=>0.65,length=>0.07,angle=>5},
						{size_min=>0.7,size_max=>0.75,length=>0.0625,angle=>4},
						{size_min=>0.8,size_max=>0.95,length=>0.05,angle=>2.5},
						{size_min=>1.0,size_max=>1.25,length=>0.045,angle=>2},
						{size_min=>1.3,size_max=>1.6,length=>0.0375,angle=>1},
						{size_min=>1.65,size_max=>2.5,length=>0.0375,angle=>1},
						{size_min=>2.55,size_max=>999,length=>0.03,angle=>0.5},
					],
					1.75 =>[
						{size_min=>0.4,size_max=>0.55,length=>0.055,angle=>4},
						{size_min=>0.6,size_max=>0.65,length=>0.055,angle=>3},
						{size_min=>0.7,size_max=>0.75,length=>0.05,angle=>2.5},
						{size_min=>0.8,size_max=>0.95,length=>0.045,angle=>2},
						{size_min=>1.0,size_max=>1.25,length=>0.0375,angle=>1},
						{size_min=>1.3,size_max=>1.6,length=>0.03,angle=>0.5},
						{size_min=>1.65,size_max=>2.5,length=>0.03,angle=>0.5},
						{size_min=>2.55,size_max=>999,length=>0.025,angle=>0.5},
					],
					2.0 =>[
						{size_min=>0.4,size_max=>0.55,length=>0.045,angle=>3},
						{size_min=>0.6,size_max=>0.65,length=>0.0375,angle=>2},
						{size_min=>0.7,size_max=>0.75,length=>0.0375,angle=>1.5},
						{size_min=>0.8,size_max=>0.95,length=>0.03,angle=>1},
						{size_min=>1.0,size_max=>1.25,length=>0.03,angle=>1},
						{size_min=>1.3,size_max=>1.6,length=>0.025,angle=>0.5},
						{size_min=>1.65,size_max=>2.5,length=>0.02,angle=>0.5},
						{size_min=>2.55,size_max=>999,length=>0.02,angle=>0},
					],
	};
	my $type;
	if($par{slot_length}/$par{slot_size} <= 1.5){
		$type = 1.5;
	}elsif($par{slot_length}/$par{slot_size} > 1.5 and $par{slot_length}/$par{slot_size} <= 1.75){
		$type = 1.75;
	}elsif($par{slot_length}/$par{slot_size} > 1.75 and $par{slot_length}/$par{slot_size} <= 2){
		$type = 2.0;
	}elsif($par{slot_length}/$par{slot_size} > 2){
		return 0;
	}
	my $result;
	foreach my $tmp (@{$info->{$type}}){
		if($par{slot_size} >= $tmp->{size_min} and $par{slot_size} <= $tmp->{size_max}){
			$result = 1;
			return $tmp;
		}
	}
	unless ($result){
		return 0;
	}
}

__END__