#!/usr/local/bin/perl
#  Usage: perl Bom_chk_fix.pl
#  Neal Ouchi
#  Combination of jumper table script, empty script & kit symbol fixes.
#######################################################
# Revision History
#######################################################
# 17 Feb 2012 Dale Blankenship
# Added HDR_BLK and HDR_RED type to "NO JUMPER SHUNT" list,
# Initialized variable $EMPTY_count to zero.
#######################################################
# 01 Feb 2011 Dale Blankenship
# Added HDR_BLU type to "NO JUMPER SHUNT" list
#######################################################

#######################################################
# Purpose of Script
#######################################################
# The purpose of this script is to extract the header information from a BOM (bill of material)
# and create a jumper table with shunt information from it and to input a BOM file (with the Rose_template2.bom template)
# and create a new BOM file by replacing a components Quantity total
# with 0 (zero) when its Material type is classified as "Empty"
# Fixes the kit symbol issues with the reference designators.
#######################################################  

sub printhelp
  {
print <<ENDOFHELP;

  Syntax:
  >Bom_chk_fix.pl -bom <Filename>  -jto <Filename>  
  
    -bom  The Bill of Materials
    -jto  The jumper table output file
 
ENDOFHELP
  exit();
  }

###  Data file setup area  ###
#  parse the command line  #

if (!@ARGV)
  {
  &printhelp;
  }

while ($arg = shift(@ARGV))
  {
  if ($arg eq "-bom")
    { $info_file = shift(@ARGV); }
  elsif ($arg eq "-jto")
    { $report_file = shift(@ARGV); }
  elsif ($arg eq "-A")
    { $change_A=1; }  
  elsif ($arg =~ "^-")
    { &printhelp; }
  }

open(OUT,">$report_file") || die "Can't open list $report_file \n";
{
  printf OUT ("[Jumper Settings]\n");
  printf OUT ("[The jumper shunts IPN#700000-842 should be installed\n");
  printf OUT ("on only the headers with shunt information]\n");
  printf OUT ("\n");
  printf OUT ("%-10s%-10s%s\n", "JUMPER", "CONFIGURATION");
  printf OUT ("------------------------------\n");
}
#######################################################
# Subroutine execution
#######################################################
&shunt();
&empty();

#######################################################

#######################################################
# Subroutines
#######################################################
sub shunt
{
open(IN,$info_file) || die "Can't open list $info_file \n";
while (<IN>)
{
   $line = $_;
   chomp($_);
   if ($line =~ "\",SHUNT")
   {
     ($ipn,$jumper,$mfg_loc) = split(/\"/,$_);
     @jmpr = split(/\,/,$jumper);
     $_=$jumper;
     $jump_name[$j]=$_;
#     printf "Jumper_Name = $jump_name[$j]  **$jmpr[0] $jmpr[1]\n";
     @loc = split(/\,/,$mfg_loc);
     ($a,$b,$c,$d,$e,$f,$g) = split(/\,/,$mfg_loc);
     $_= $g;
     $jump_loc[$i]=$_;
#     printf "1 jump_name[$j] $jump_loc[$i]\n";
     for($j=0; $j<=$#jmpr; $j++)
     {
       $found=0;
       printf OUT ("%-10s%-10s%s\n", "$jmpr[$j]", "$jump_loc[$i]");
     }
   }
     elsif ($line =~ "\,SHUNT")
     {
       ($junk,$junk1,$junk2,$junk3,$junk4,$junk5,$junk6,$junk7,$junk8,$junk9,$junk10) = split(/\,/,$_);
       $_=$junk4;
       $jump_name[$k]=$_;
       $_= $junk10;
       $jump_loc[$b]=$_;
#       printf "2 Jumper_loc = $jump_loc[$b] jumper_name = $jump_name[$k]\n";
       printf OUT ("%-10s%-10s%s\n", "$jump_name[$k]", "$jump_loc[$b]");
     }
## 17 Feb 2012 DCB: added HDR_RED and HDR_BLK to line below
       if ($line =~ "\",HDR," || $line=~ "\",HDR_BLU," || $line=~ "\",HDR_RED," || $line=~ "\",HDR_BLK,")
       {
         ($misc,$misc1,$misc2) = split(/\"/,$_);
         @jml = split(/\,/,$misc1);
         foreach $jmp (@jml)
         {
           printf OUT ("%-10s%-10s%s\n", "$jmp", "NO JUMPER SHUNT");
         }
       }
## 17 Feb 2012 DCB: added HDR_RED and HDR_BLK to line below
         elsif ($line =~ "\,HDR," || $line=~ "\,HDR_BLU," || $line=~ "\,HDR_RED," || $line=~ "\,HDR_BLK,")
         {
           ($nun,$nun1,$nun2,$nun3,$nun4,$nun5,$nun6,$nun7,$nun8,$nun9,$nun10) = split(/\,/,$_);
           @jp = split(/\,/,$nun4);
           $_=$nun4;
           $jm[$n]=$_;
           printf OUT ("%-10s%-10s%s\n", "$jm[$n]", "NO JUMPER SHUNT");
         }
             if  ($line =~ "\",EMPTY," && $line =~ "\HDR" && $change_A)
              {
                ($emp,$emp1,$emp2) = split(/\"/,$_);
                @empl = split(/\,/,$emp1);
                foreach $emp (@empl)
                   {
                     printf OUT ("%-10s%-10s%s\n", "$emp", "HEADER IS NOT POPULATED");
                   }
              }
                elsif ($line =~ "\,EMPTY," && $line =~ "\HDR" && $change_A)
                     {
                       ($nop,$nop1,$nop2,$nop3,$nop4,$nop5,$nop6,$nop7,$nop8,$nop9,$nop10) = split(/\,/,$_);
                       @np = split(/\,/,$nop4);
                       $_=$nop4;
                       $em[$n]=$_;
                       printf OUT ("%-10s%-10s%s\n", "$em[$n]", "HEADER IS NOT POPULATED");
                     }
}
close (IN);
close (OUT);
}

sub empty
{
open(new_BOM, "> BOM_Update.txt");                                # creating an output file
open(logfile, "> BOM_logfile.txt");                           
open(IN,$info_file) || die "Can't open list $info_file \n";

   $EMPTY_count = 0;		# 17 Feb 2012 DCB: initialize empty component counter to zero
# Otherwise it prints "Found  empty parts" instead of "Found 0 empty parts" when none exist   


@alpha = ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
while (<IN>) {
        chomp;          					  # chomp used to remove carrage return


################################################################################
# Matching Definition
################################################################################
# (m/(ARGUMENT_1)(ARGUMENT_2)...(ARGUMENT_N)/i) -> matching syntax in perl
# (.*)------------------> . = any characer and * = 0 or more occurances
# (.*) matches any character occuring 0 or more times. 
# (\,)------------------> \ = special character indicator and , = comma character
# (\,) matches a comma
# (\d+)-----------------> \d = any digit and + = 1 or more 
# (\d+) matches any digit occuring 1 or more times
# (EMPTY) matches the word "EMPTY"
# i used to match non case sensitive
#################################################################################
# in the if statement below:
#################################################################################
# (ARGUMENT_1) = (.*) = all text just before comma of components Quantity total = perl stores (ARGUMENT_1) as $1 (default)
# (ARGUMENT_2) = (\,) = commma just before components Quantity total = perl stores (ARGUMENT_2) as $2 (default)
# (ARGUMENT_3) = (\d+) = components Quantity total = perl stores (ARGUMENT_3) as $3 (default)
# (ARGUMENT_4) = (\,) = commma just after components Quantity total = perl stores (ARGUMENT_4) as $4 (default)
# (ARGUMENT_5) = (.*) = all text just after comma of components Quantity total and before EMPTY = perl stores (ARGUMENT_5) as $5 (default)
# (ARGUMENT_6) = (EMPTY) = the text "EMPTY" = perl stores (ARGUMENT_6) as $6 (default)
# (ARGUMENT_7) = (.*) = all text just after "EMPTY" = perl stores (ARGUMENT_7) as $7 (default)
#################################################################################

   $line = $_;
   if ($line =~ "\",SHUNT")
   {
     $callout = 1;
     ($ipn,$jumper,$mfg_loc) = split(/\"/,$_);
     @jmpr = split(/\,/,$jumper);
     for($j=0; $j<=$#jmpr; $j++)
     {
       $location[$j+$c]= "X".@jmpr[$j];
       push @save_ref, $location[$j+$c];
     }
     $c = $c + $#jmpr;
     @stuff = split(/\,/,$ipn);
#     printf "IPN=$ipn Stuff=@stuff \n";
     $total = $total+@stuff[2];
#     printf "total=$total\n";
  }
   elsif ($line =~ "\,SHUNT")
   {
      $callout = 1;
   	 $c++;
      ($junk,$junk1,$junk2,$junk3,$junk4,$junk5,$junk6,$junk7,$junk8,$junk9,$junk10) = split(/\,/,$_);
      $total = $total+$junk2;
#      printf "Total=$total\n";
      $location[$c] = "X".$junk4;
      push @save_ref, $location[$c];

    }

    elsif(m/(.*)(\,)(\d+)(\,)(.*)(EMPTY)(.*)/i)          # Searches for lines with "EMPTY"
    {	                                         #open if bracket
       $quantity = 0;                              #set quanity string to 0 (zero)
       $EMPTY_count++;                             #counter used for "EMPTY" occurances
       $line_count++;				 #counter used to track lines read
       $restend = $7;
       printf (logfile "found EMPTY part on line $line_count\n"); #prints out matched text  
#*****************************************       
       if($line =~ /\d+\,NORMAL\,\"/)
       {
          ($misc0,$misc1,$misc2,$misc3,$misc4) = split(/\"/,$line);
           if ($misc3){$misc3 = "\"".$misc3."\"";}
           @cr = split(/\,/,$misc1);
           @qty = split(/\,/,$misc0);
           $q1 = $#cr+1;
           push @save_ref, @cr;
           if ($q1 == $qty[2])
           {
         	 $misc1=1;
             printf (new_BOM "@qty[0]\,@qty[1]\,$quantity\,@qty[3]\,\""); #prints out matched text
             for ($k = 0; $k<$#cr; $k++)
             {
                 printf( new_BOM "@cr[$k]\,");
             }
             printf (new_BOM "@cr[$#cr]\"$misc2$misc3$misc4\n"); #prints out matched text
           }
           else 
           {
             printf (new_BOM "ne $#cr $qty[2]\n");
             printf (logfile "Strange but miss matched in Refdes vs quanitities on line $line_count\n");
           }
        }
        elsif ($line =~ /\d+\,NORMAL/)
        {  
          ($nun,$nun1,$nun2,$nun3,$nun4,$nun5,$nun6) = split(/\,/,$_);
           $_=$nun4;
           $jm[$n]=$_;
           if ($nun2 == 1)
           {
         	  $misc1=1;
              printf (new_BOM "$nun\,$nun1\,$quantity\,$nun3\,$nun4\,$nun5$restend\n"); #prints out matched text
              push @save_ref, $nun4;
           }
           else 
           {
         	  for($x=0; $x<$nun2; $x++)
         	   {
         	   	 @rdes[$x] = $nun4.@alpha[$x]; 
               }
              printf (new_BOM "$nun\,$nun1\,$nun2\,$nun3\,\""); #prints out matched text
              for ($k = 0; $k<$#rdes; $k++)
              {
                  printf( new_BOM "@rdes[$k]\,");
              }
              printf (new_BOM "@rdes[$#rdes]\"\,$nun5$restend\n"); #prints out matched text
              printf (logfile "Changed the Refdes $line_count $nun4 changed to @rdes\n");
              push @save_ref, @rdes;
         	}
            
         }        
#************************************************************
 			
     }                                              #closing if bracket
     elsif ($line =~ /^Callouts/)
     {
         $mechanical = 1;
         printf (new_BOM "$line\n");			 #print entire line read
     }
     else
     {
       $NON_EMPTY_count++;			 #counter used for NON "EMPTY" occurances
       $line_count++;				 #counter used to track lines read
#       printf (new_BOM "$_\n");			 #print entire line read
       if ($callout)
       {
            chomp(@location);
            printf (new_BOM " \,700000-842,$total,NORMAL,\"");
            for ($k = 0; $k<$#location; $k++)
            {
                printf( new_BOM "@location[$k]\,");
            }
            printf (new_BOM "@location[$#location]\",SHUNT,MOLEX,15\-29\-1024,SHUNT,CONNLF,?\n");	 #print entire line read
            printf (logfile "On line $line_count changed jumpers to @location\n");
            $callout = 0;
       }
       if($line =~ /\d+\,NORMAL\,\"/)
       {
          ($misc0,$misc1,$misc2) = split(/\"/,$line);
        
           @cr = split(/\,/,$misc1);
           @qty = split(/\,/,$misc0);
           $qty[0] = $#cr+1;
           if ($mechanical)
           {
              for ($i=0; $i<=$#cr; $i++) 
              {
                 for ($j=$i+1; $j<=$#save_ref; $j++) 
                 {
                    $_ = $save_ref[$j];
                    if (/(\d+)X(.*)/)
   	              {
                       $prf = $1+1;
                       if (@cr[$i] eq $2)
     	                 {
    	                  @cr[$i] = $prf."X".$2;
    	                 }
                    }
                    elsif (/^X(.*)/)
                    {
                       if (@cr[$i] eq $1)
     	                 {
    	                  @cr[$i] = "1X".$1;
    	                 }
                    }
                    elsif (@save_ref[$j] eq @cr[$i])
                    {
    	                  @cr[$i] = "X".@cr[$i];
                    }   
                 }
              }
           }
           push @save_ref, @cr;
           if ($qty[0] == $qty[2])
           {
         	 $misc1=1;
             printf (new_BOM "$line\n"); #prints out matched text
           }
           else 
           {
             printf (new_BOM "ne $#cr $qty[2]\n");
             printf (logfile "Strange but miss matched in Refdes vs quanitities on line $line_count\n");
           }
        }
        elsif ($line =~ /\d+\,NORMAL/)
        {  
          ($before, $after)= split(/\,NORMAL\,\w+\,/);
          ($nun,$nun1,$nun2,$nun3,$nun4,$nun5,$nun6) = split(/\,/,$_);
           $_=$nun4;
           $new_nun4 = $nun4;
           $jm[$n]=$_;
           if ($mechanical)
           {
               for ($j=0; $j<=$#save_ref; $j++) 
               {
                  $_ = @save_ref[$j];
                  if (/(\d+)X(.*)/)
 	            {
                     $prf = $1+1;
                     if ($nun4 eq $2)
     	               {
    	                  $new_nun4 = $prf."X".$nun4;
   	                  printf (logfile "On line $line_count fixed the $nun4 to be $new_nun4\n");
                     }
                  }
                  elsif (/X(.*)/)
                  {
                     if ($nun4 eq $1)
     	               {
    	                  $new_nun4 = "1X".$nun4;
                        printf (logfile "On line $line_count fixed the $nun4 to be $new_nun4\n");
    	               }
                  }
                  elsif ($nun4 eq @save_ref[$j])
                  {
                       $new_nun4 = "X".$nun4;
                       printf (logfile "On line $line_count fixed the $nun4 to be $new_nun4\n");
                  }
               }
           }
           if ($nun2 == 1)
           {
         	  $misc1=1;
#              printf (new_BOM "$line\n");         #prints out matched text
              printf (new_BOM "$nun\,$nun1\,$nun2\,$nun3\,$new_nun4\,$after\n"); #prints out matched text
             push @save_ref, $new_nun4;
           }
           else 
           {
         	  for($x=0; $x<$nun2; $x++)
         	   {
         	   	 @rdes[$x] = $new_nun4.@alpha[$x]; 
               }
              printf (new_BOM "$nun\,$nun1\,$nun2\,$nun3\,\""); #prints out matched text
              for ($k = 0; $k<$#rdes; $k++)
              {
                  printf( new_BOM "@rdes[$k]\,");
              }
              printf (new_BOM "@rdes[$#rdes]\"\,$after\n"); #prints out matched text
              printf (logfile "On line $line_count changed $nun4 to @rdes\n");
              push @save_ref, $new_nun4;
         	}
         } 
         else
         {
             printf (new_BOM "$line\n");			 #print entire line read
         } 

     }

} 						 # closing bracket for while (<BOMF>)


# Checking for Duplicate Refdes numbers
for ($i=0; $i<$#save_ref; $i++)
{ 
      for ($j=$i+1; $j<=$#save_ref; $j++) 
      {
   	    if (@save_ref[$i] eq @save_ref[$j])
     	    {
             printf (logfile "Duplicate Refdes End Check @save_ref[$i] = @save_ref[$j]\n");
    	    }
       }
}


close IN;
close new_BOM;
close logfile;

printf ( " ******************************************************\n");
printf ( " -------------------------------------------------------\n");
printf ( " Found $EMPTY_count empty parts\n");            
#printf ( $EMPTY_count + $NON_EMPTY_count\n);
printf ( " Read $line_count total lines\n");
printf ( " -------------------------------------------------------\n");
printf ( " *******************************************************\n");
printf ( " -------------------------------------------------------\n");
printf ( " Refer to \"BOM_logfile.txt\" for \"EMPTY\" line numbers\n");
printf ( " -------------------------------------------------------\n");
#-------------------------------------------------------------------------------
# Coding Ends Here
#-------------------------------------------------------------------------------
}

