#!/bin/awk -f

#	cmap
#
#	Create country maps.  One character per country.
#	Reads bmap, look, spy, report, relations, nation, dump 
#	to build new map.

function abs(x) {
  if (x>0) return x;
  return -x;
}
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);
}

#
#	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;

  flood=1;

# some defaults so I don't have to parse *everything*
#  country[82]="harmless";
#  number["harmless"]=82;
#  coun=82;
#  password="picky";
#  width=192;
#  height=96;
}


/^World size is [0-9]+ by [0-9]+./ {
  width = $4;
  height= $6 + 0;
}


/.* Nation Report/ {
  if ($1 in number) coun=number[$1];
  country[coun]=$1;
  number[$1]=coun;
}  

/^.+ \(#[0-9]+\) .+ [0-9]+% efficient .* @ .+,.+/ {
  i=index($0,"(#");
  j=index($0,")");
  coun=truncwhite(substr($0,i+2,j-i-2));
  name=truncwhite(substr($0,1,i-1));
  country[coun]=name;
  number[name]=coun;
  
  i=match($0,"[0-9]+%");
  sectype=substr($0,j+1,i-j-2);
  
  if (sectype == " sea") sec=".";
  else if (sectype == " mountain") sec="^";
  else if (sectype == " sanctuary") sec="s";
  else if (sectype == " wasteland") sec="/";
  else if (sectype == " wilderness") sec="-";
  else if (sectype == " capital") sec="c";
  else if (sectype == " uranium mine") sec="u";
  else if (sectype == " park") sec="p";
  else if (sectype == " defense plant") sec="d";
  else if (sectype == " shell industry") sec="i";
  else if (sectype == " mine") sec="m";
  else if (sectype == " gold mine") sec="g";
  else if (sectype == " harbor") sec="h";
  else if (sectype == " warehouse") sec="w";
  else if (sectype == " airfield") sec="*";
  else if (sectype == " agribusiness") sec="a";
  else if (sectype == " oil field") sec="o";
  else if (sectype == " light manufacturing") sec="j";
  else if (sectype == " heavy manufacturing") sec="k";
  else if (sectype == " fortress") sec="f";
  else if (sectype == " technical center") sec="t";
  else if (sectype == " research lab") sec="r";
  else if (sectype == " nuclear plant") sec="n";
  else if (sectype == " library/school") sec="l";
  else if (sectype == " highway") sec="+";
  else if (sectype == " radar installation") sec=")";
  else if (sectype == " weather stn (useless)") sec="!";
  else if (sectype == " retirement home (useless)") sec="!";
  else if (sectype == " headquarters") sec="!";
  else if (sectype == " bridge head") sec="#";
  else if (sectype == " bridge span") sec="=";
  else if (sectype == " bank") sec="b";
  else if (sectype == " refinery") sec="%";
  else if (sectype == " enlistment center") sec="e";
  else {
    printf("# Unknown sector type `%s'\n",sectype);
    printf("# %s\n",$0);
    sec="?";
  }

  j=index($0,"%");
  seceff = substr($0,i,j-i);

  for (i=1;i<=NF;i++) if ($i=="with") break;

  while ($i == "with") {
    approx=0;
    i++;
    if ($i == "approx") { i++; approx=4; }
    if ($(i+1)=="civ") {
      secciv = $i + approx;
    } else if ($(i+1)=="mil") {
      secmil = $i + approx;
    } else {
      printf("# Expected either civ or mil.  Got %s\n",$(i+1)) ;
    }
    i += 2;
  }
  
  i++;
  n=split($i,a,",");
  sect=$i;
  val[sect,"x"]=a[1];
  val[sect,"y"]=a[2];
  val[sect,"des"]=sec;
  val[sect,"eff"]=seceff;
  val[sect,"civ"]=secciv;
  val[sect,"mil"]=secmil;
  own[sect]=coun;
  oldown[sect]=coun;
}

/^SPY report/ {
  getline;
  getline;
  if ($0 != "   sect   type own  eff  civ  mil  shl  gun  iron  pet  food") {
    printf("# Spy report error\n");
  }

  getline;
  while (length($0)>0) {
    if ($1 != "Spies") {
      split($1,a,"[ ,]");
      sect=$1;
    
      val[sect,"x"]=a[1];
      val[sect,"y"]=a[2];
      val[sect,"des"]=$2;
      own[sect]=oldown[sect]=$3;
      val[sect,"eff"]=$4;
      val[sect,"civ"]=$5;
      val[sect,"mil"]=$6;
      val[sect,"shell"]=$7;
      val[sect,"gun"]=$8;
      val[sect,"iron"]=$9;
      val[sect,"pet"]=$10;
      val[sect,"food"]=$11;
      if (val[sect,"mil"]==0 && val[sect,"civ"]==0) val[sect,"mil"]=1;
    }
    getline;
  }
}

/^Kawhomp! Mine detected by .+ \(#[0-9]+\) in .+,.+!/ {
  sect=substr($NF,1,length($NF)-1);
  mine[sect]=20;
}


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

  colskip = match(header[0],"[0-9\-]");
  if (!colskip) printf("# error reading bmap\n");
  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;

  top="";
  getline;
  while (match($0,"[0-9\-]")<colskip) {
    y=$1;
    bottom=y;
    if (top=="") top=y;
    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,"[a-zA-Z\/^\.\\*+)!#=%\-@]")) {
          bdes[x,y]=des;
	}
      }
      x++;
      if (x>=width/2) x -= width;
    }
    getline;
  }
}


/ *DUMP SECTOR/ { mode="dump"; stat=1; next; }
/^ *# *name *tech *research *education *status/ { mode="report"; stat=1; next; }
/^.* Diplomatic Relations Report/ { mode="relations"; stat=1; next; }
/#.*last access.*time.*status.*country name/ { mode="coun"; stat=1; next; }


{
  if (mode=="coun") {
    if (NF>6) {
      name=substr($0,42);
      number[name]=$1;
      country[$1]=name;
    } else mode="";
  } else if (mode=="dump") {
    if (stat==1) {
      for (i=1;i<=NF;i++) header[i]=$i;
      nheader=NF;
      stat=2;
      break;
    }
    
    if (NF != nheader) {
      stat=0;
    }
    
    if (stat==2) {
      for (i=1;i<=nheader;i++) temp[header[i]] = $i;
      sect = temp["x"] "," temp["y"];
#      for (i=1;i<=nheader;i++) val[sect,header[i]] = $i;
      
      if (val[sect,"*"]=="*") oldown[sect]=0;
      else if ("own" in temp) oldown[sect]=temp["own"];
      else oldown[sect]=coun;
      if ("own" in temp) own[sect]=temp["own"];
      else own[sect]=coun;
    }
  } else if (mode=="relations") {
    if (stat<3) {
      stat++;
      next;
    }
    if (stat==3) {
      if (NF>3) {
	if (!($2 in number)) {
	  number[$2]=substr($1,1,length($1)-1);
	  country[number[$2]]=$2;
	  next;
	}
      } else mode="";
    }
  } else {
    mode="";
    stat=0;
    next;
  }

}




END {
  if (flood) {
    do {
      added=0;
      for (sect in bdes) {
	if (bdes[sect]!="." && !(sect in own)) {
	  split(sect,a,",");
	  x=a[1];
	  y=a[2];
	  if ((x+2,y) in own) { added++; own[x,y]=own[x+2,y]; }
	  else if ((x-2,y) in own) { added++; own[x,y]=own[x-2,y]; }
	  else if ((x+1,y+1) in own) { added++; own[x,y]=own[x+1,y+1]; }
	  else if ((x+1,y-1) in own) { added++; own[x,y]=own[x+1,y-1]; }
	  else if ((x-1,y+1) in own) { added++; own[x,y]=own[x-1,y+1]; }
	  else if ((x-1,y-1) in own) { added++; own[x,y]=own[x-1,y-1]; }
	}
      }
    } while (added);
  }



  abbrev["0"]="-";
  country["-"]="Waffen";
  number["Waffen"]=0;

  abbrev[number["Mr.X"]]="X";
  country["X"]="Mr.X";

  for (sect in own) {
    if (own[sect]!=int(own[sect])) {
      printf("sector %s owned by %s\n",sect,own[sect]);
    }
  }

  for (sect in own) sects[own[sect]]++;
  for (coun in sects) {
    if (!(coun in abbrev)) {
      if (!(substr(country[coun],1,1) in country)) {
	abbrev[coun]=substr(country[coun],1,1);
	country[abbrev[coun]]=country[coun];
      }
    }
  }
  for (coun in sects) {
    if (!(coun in abbrev)) {
      if (!(toupper(substr(country[coun],1,1)) in country)) {
	abbrev[coun]=toupper(substr(country[coun],1,1));
	country[abbrev[coun]]=country[coun];
      }
    }
  }
  for (coun in sects) {
    if (!(coun in abbrev)) {
      if (!(tolower(substr(country[coun],1,1)) in country)) {
	abbrev[coun]=tolower(substr(country[coun],1,1));
	country[abbrev[coun]]=country[coun];
      }
    }
  }
  for (coun in sects) {
    if (!(coun in abbrev)) {
      s="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_+=\\|][{}';:\"/.,<>`";
      for (i=1;i<=length(s);i++) {
	if (!(substr(s,i,1) in country)) {
	  abbrev[coun]=substr(s,i,1);
	  country[abbrev[coun]]=country[coun];
	  break;
	}
      }
    }
  }

  wi=right-left+1;
  he=bottom-top+1;
  if (w<0) wi+=width;
  if (h<0) he+=height;

  printf("     ");
  x=left;
  for (w=0;w<wi;w++) {
    if (x>=width/2) x-=width;
    if (x<-9) printf("%1d",-x/10);
    else if (x<0) printf("-");
    else printf("%1d",x/10);
    x++;
  }
  printf("\n     ");
  x=left;
  for (w=0;w<wi;w++) {
    if (x>=width/2) x-=width;
    printf("%1d",abs(x)%10);
    x++;
  }
  printf("\n");

  y=top;
  for (h=0;h<he;h++) {
    if (y>=height/2) y-=height;
    printf("%4d ",y);
    if (y<0) j=y+height; else j=y;
    x=left;
    for (w=0;w<wi;w++) {
      if (x>=width/2) x-=width;
      if (x<0) i=(x+width)/2; else i=x/2;

      if ( (x+y) % 2 ) {
	printf(" ");
      } else {
	if (bdes[x,y]==".") printf(".");
	else if ((x,y) in own) printf("%1s",abbrev[own[x,y]]);
	else if ((x,y) in bdes) printf("?");
	else printf(" ");
      }
      x++;
    }
    printf("%4d\n",y);
    y++;
  }

  printf("     ");
  x=left;
  for (w=0;w<wi;w++) {
    if (x>=width/2) x-=width;
    if (x<-9) printf("%1d",-x/10);
    else if (x<0) printf("-");
    else printf("%1d",x/10);
    x++;
  }
  printf("\n     ");
  x=left;
  for (w=0;w<wi;w++) {
    if (x>=width/2) x-=width;
    printf("%1d",abs(x)%10);
    x++;
  }
  printf("\n\n");


  x=0;
  for (coun in abbrev) {
    printf("  %14s(#%2s) - %1s",country[coun],coun,abbrev[coun]);
    x++;
    if (x>2) {
      x=0;
      printf("\n");
    }
  }
  printf("\n\n");


  printf("Number array\n");
  for (i in number) {
    printf("%s - %s - %s - %s\n",i,number[i],country[number[i]],abbrev[number[i]]);
  }
  printf("sects array\n");
  for (i in sects) {
    printf("%s - %s\n",i,sects[i]);
  }
#  printf("own array\n");
#  for (sect in own) {
#    printf("%s - %s\n",sect,own[sect]);
#  }
}

