#!/bin/awk -f
#
#	launch satellites to uncovered territory
#
#
#	Reads the following file formats.
#		dump
#		nation
#		report
#		relations
#		ship
#		cargo
#		unit
#		lcargo
#		spy
#		look  
  
function max(x,y) {
  if (x>y) return x;
  return y;
}
function min (x,y) {
  if (x<y) return x;
  return y;
}

function num(str) {
  return substr(str,1,length(str)-1);
}
#
#	Turns a letter into a name.  Tries the first letter, if that
#	isn't a commodity, tries the last letter (useful for ship, unit,
#	and prod outputs)
#
function commstr(str) {
  char=substr(str,1,1);
  if (char == "c") return "civ";
  if (char == "m") return "mil";
  if (char == "u") return "uw";
  if (char == "f") return "food";
  if (char == "s") return "shell";
  if (char == "g") return "gun";
  if (char == "p") return "pet";
  if (char == "i") return "iron";
  if (char == "d") return "dust";
  if (char == "b") return "bar";
  if (char == "o") return "oil";
  if (char == "l") return "lcm";
  if (char == "h") return "hcm";
  if (char == "r") return "rad";

  char=substr(str,length(str),1);
  if (char == "c") return "civ";
  if (char == "m") return "mil";
  if (char == "u") return "uw";
  if (char == "f") return "food";
  if (char == "s") return "shell";
  if (char == "g") return "gun";
  if (char == "p") return "pet";
  if (char == "i") return "iron";
  if (char == "d") return "dust";
  if (char == "b") return "bar";
  if (char == "o") return "oil";
  if (char == "l") return "lcm";
  if (char == "h") return "hcm";
  if (char == "r") return "rad";
  return "";
}

#
#	Truncate starting and ending whitespace from a string
#
function truncwhite(str,  i,j) {
  for (i=1;i<=length(str) && substr(str,i,1) ~ "[ \t\r\n]";i++) ;
  for (j=length(str);j>i && substr(str,j,1) ~ "[ \t\r\n]";j--) ;
  return (substr(str,i,j-i+1));
}


BEGIN {
  SUBSEP=",";
  mode="";
  stat=0;
    if (etu=="") etu=60;

  ships=0;
  shipnamlen=16;
  
# some defaults so I don't have to parse *everything*
  width=192;
  height=96;

  weight["civ"]=1;	packing["civ"]=1;
  weight["mil"]=1;	packing["mil"]=1;
  weight["uw"]=2;	packing["uw"]=1;
  weight["food"]=1;	packing["food"]=10;
  weight["shell"]=1;	packing["shell"]=10;
  weight["gun"]=10;	packing["gun"]=10;
  weight["pet"]=1;	packing["pet"]=10;
  weight["iron"]=1;	packing["iron"]=10;
  weight["dust"]=5;	packing["dust"]=10;
  weight["bar"]=50;	packing["bar"]=5;
  weight["oil"]=1;	packing["oil"]=10;
  weight["lcm"]=1;	packing["lcm"]=10;
  weight["hcm"]=1;	packing["hcm"]=10;
  weight["rad"]=8;	packing["rad"]=10;
}

/[0-9\-]+,[0-9\-]+ efficiency [0-9]+%, max range [0-9]+/ {
  radar[$1]=$NF;
}

/.* #[0-9]+ at [0-9\-]+,[0-9\-]+ efficiency [0-9]+%, max range [0-9]+/ {
   n=substr($(NF-7),2);
   satellite[n]=$(NF-5);
   range[n]=$(NF-5);
}


/^bmap/ {    
  getline;
  header[0]=$0
  getline;
  header[1]=$0;

  colskip = match(header[0],"[0-9\-]");
  if (!colskip) printf("error reading bmap\n") >> "/dev/tty";
  columns = length(header[0])-colskip+1;
  
  left=substr(header[0],colskip,1)*10+substr(header[1],colskip,1);
  right=substr(header[0],length(header[0]),1)*10+substr(header[1],length(header[1]),1);
  left2=substr(header[0],colskip+1,1)*10+substr(header[1],colskip+1,1);
  right2=substr(header[0],length(header[0])-1,1)*10+substr(header[1],length(header[1])-1,1);
  
  if (left2<left) left = -left;
  if (right2>right) right = -right;

  getline;
  while (match($0,"[0-9\-]")<colskip) {
    y=$1;
    x=left;
    for (col=colskip;col<columns;col++) {
      if ( (x+y)/2 == int((x+y)/2) ) {
	des=substr($0,col,1);
	if (des=="?") des="+";
	if (match(des,"[s^cupdimghw\\*aojkftrnl+)!#=b%eX\-]")) {
          bdes[x,y]=des;
	}
      }
      x++;
      if (x>=width/2) x -= width;
    }
    getline;
  }
}

/.* Diplomatic Relations Report/ {
  i=match($0,"Diplomatic Relations Report");
  name=truncwhite(substr($0,1,i-2));
  getline; getline;
  while (getline) {
    if (NF<4) break;
    relname=truncwhite(substr($0,6,20));
    number[relname]=substr($1,1,length($1)-1);
    country[number[relname]]=relname;
    relation[name,relname]=truncwhite(substr($0,28,10));
    relation[relname,name]=truncwhite(substr($0,39,10));
  }

  next;
}


/ *DUMP SECTOR/ { mode="dump"; stat=1; next; }
/^ *# *name *tech *research *education *status/ { mode="report"; stat=1; next; }
/^shp#     ship type       x,y   fl  eff civ mil  uw  fd pn he xl ln mob fuel tech/ { mode="ship"; stat=1; next; }
/^shp# ship type           x,y   flt  eff  sh gun pet irn dst bar oil lcm hcm rad/ { mode="cargo"; stat=1; next; }
/ *# unit type * x,y * a * eff fort * mu food fuel tech retr rad xl ship/ { mode="unit"; stat=1; next; }
/ *#    type                x,y    w  eff  mu att def tech ran hard   s\/l nuke/ { mode="plane"; stat=1; next; }
/ *lcm hcm avail tech \$/ {mode="ssb"; stat=1; next;}
/ *cargos & capabilities/ {mode="ssc"; stat=1; next; }
/ *def  d  s  y  g  r  d  n  l  l/ {mode="sss"; stat=1; next; }
/ *lcm hcm mil guns shells avail tech  \$/ {mode="slb"; stat=1; next;}
/^ *capabilities$/ {mode="slc"; stat=1; next; }
/ *att def vul  d  s  y  d  g  c  m  m  f  c  u  l/ {mode="sls"; stat=1; next;}
/ *lcm hcm crew avail tech  $/ { mode="spb"; stat=1; next; }
/ *acc load att def ran fuel stlth/ { mode="sps"; stat=1; next; }

{
  if (mode=="slc" || mode=="spc") {
    if (stat==1 && length($0)>26) {
      name=truncwhite(substr($0,1,20));
      nf=split(substr($0,22),a,"[ \t/]*");
      for (i=2;i<=nf;i++) {
	if (a[i] ~ "[0-9]+[cmufsgpidbolhr]") {
	  unitcargo[name,commstr(a[i])] = num(a[i]);
	} else {
	  capability[name] = capability[name] " " a[i] " ";
	}
      }
      next;
    } else {
      mode="";
      stat=0;
      next;
    }
  } else if (mode=="plane") {
    if (stat==1) {
      planes=0;
      for (i in planeorder) delete planeorder[i];
      stat=2;
    }
    if (stat==2 && NF > 2) {
      name=truncwhite(substr($0,6,20));
      planeorder[planes++]=$1;
      planename[$1]=name;
#      planename[$1]=$2;	
      planeown[$1]=coun;
      planesect[$1]=truncwhite(substr($0,25,9));
      planewing[$1]=substr($0,36,1);
      planeeff[$1]=substr($0,38,3);
      planemob[$1]=substr($0,43,3);
      planeatt[$1]=substr($0,47,3);
      planedef[$1]=substr($0,51,3);
      planetech[$1]=substr($0,55,4);
      planeran[$1]=substr($0,60,3);
      planehard[$1]=substr($0,64,4);
      next;
    } else {
      mode="";
      stat=0;
      next;
    }
  } else if (mode=="lcargo") {
    if (stat==1) {
      units=0;
      for (i in unitorder) delete unitorder[i];
      stat=2;
    }
    if (stat==2 && NF > 2) {
      name=truncwhite(substr($0,6,shipnamlen));
      unitorder[units++]=$1;
      unitname[$1]=name;
      unitown[$1]=coun;
      unitsect[$1]=truncwhite(substr($0,25,9));
      unitarmy[$1]=substr($0,34,1);
      uniteff[$1]=substr($0,36,3);
      unitcargo[$1,"rad"]=num($NF);
      unitcargo[$1,"hcm"]=num($(NF-1));
      unitcargo[$1,"lcm"]=num($(NF-2));
      unitcargo[$1,"oil"]=num($(NF-3));
      unitcargo[$1,"bar"]=num($(NF-4));
      unitcargo[$1,"dust"]=num($(NF-5));
      unitcargo[$1,"iron"]=num($(NF-6));
      unitcargo[$1,"pet"]=num($(NF-7));
      unitcargo[$1,"gun"]=num($(NF-8));
      unitcargo[$1,"shell"]=num($(NF-9));
      next;
    }
  } else {
    mode="";
    stat=0;
    next;
  }
  
}

# calculate hexes between two sectors
function distance(from,to, a,b,deltax,deltay)
{
  split(from,a,",");
  split(to,b,",");

  deltax=b[1]-a[1];
  if (deltax<0) deltax = -deltax;
  if (deltax>width/2) deltax=width-deltax;
  deltay=b[2]-a[2];
  if (deltay<0) deltay = -deltay;
  if (deltay>height/2) deltay=height-deltay;

  if (deltax>deltay) return ((deltax-deltay)/2+deltay);
  return (deltay);
}


END {
  srand();

  for (n in planename) {
    if (index(capability[planename[n]]," satellite ")) {
      if (!index(capability[planename[n]]," missile ")) {
	if (!(n in satellite) && planeeff[n]==100 && planemob[n]==127) {
	  launch=0;
#	  for (i=0;i<100 && !launch;i++) {
	    x=int(rand()*width/2)*2-width/2;
	    y=int(rand()*height)-height/2;
	    if ((x+y)%2) x++;
	    sect= x "," y;
#	    if (distance(sect,planesect[n])<=etu) {
#	    printf("# %s to %s\n",planesect[n],sect);
#	      launch=1;
#	      for (s in satellite) {
#		if (distance(satellite[s],sect)<=range[s]) {
#		  launch=0;
#		  printf("# %s too close to %s(#%s)\n",sect,satellite[s],s);
#		  break;	
#		}
#	      }
#	    } else launch=0;
#	  }
#	  if (launch) {
#	    for (s in satellites) {
#	      printf("# %d from #%d\n",distance(satellite[s],sect),s);
#	    }
#	    for (r in radar) {
#	      printf("# %d from %s\n",distance(r,sect),r);
#	    }
	    printf("launch %d\n& %d,%d\n\n",n,sect);
#	  }
	}
      }
    }
  }


}
