package Constants;

# This handles reading and returning constants, as read from the file
# ~openimpetus/Comps/<compdir>/Constants

# use Error;

my $comp;
my $constants_dir="Comps/";
my $constants_name="Constants";

sub getConstantsFilename {
  return($constants_dir.$comp->{COMPFILE}."/".$constants_name);
}

sub get {
  return($comp->{$_[0]});
}

# Read in the Constants file.
sub fetch_constants {
#  my $proto=shift;
#  my $class=ref($proto) || $proto;
  my $compname=$_[0];
  my ($k, $v, %tmp, $foo);
  my ($i, @asdf);
  my $constants_path=$constants_dir.$compname."/".$constants_name;
  my $line=1;

  $comp={};
  $comp->{COMPFILE}=$compname;

  open(IN, "$constants_path") || Error::CantGetConstants("$constants_path");
  while(<IN>) {
# Get rid of leading whitespace...
    s/^\s+//;
# ...and trailing whitespace
    s/\s+$//;
# Throw away the ';' at the end of the line.
    s/;$//;
# Ignore comments...
    next if /^#/;
# ...and lines that are completely blank.
    next if /^\s*$/;
    ($k, $_)=split('=', $_, 2);
# MASTER is the dance listing
    if ($k eq MASTER) {
      $comp->{MASTER}=&process_master($_);
      next;
    } elsif ($k eq SCHOOLS) {
      $comp->{SCHOOLS}=&process_schools($_);
      next;
# Probably not needed anymore, since we're using perl.
    } elsif ($k eq ALPHABET) {
      $comp->{ALPHABET}=&process_alphabet($_);
      next;
    }
# In-line variable substitution.  If we get $foo, replace it with $tmp{$foo}
    while (/\$(\w+)/) {
      $foo=$1;
      s/\$$foo\.{0,1}/$tmp{$foo}/;
    }      
    s/"\."//g;
    s/\"//g;
    s/\\/\"/g;
    $comp->{$k}=$_;
    $tmp{$k}=$_;

  }
  close(IN);

# Theoretically, these could/should be in Constants.
  $comp->{ESQUE}=1; # as in latin-esque
  $comp->{MODERN}=2;
  $comp->{FUN_STYLE}=3; # as opposed to FUN_DANCE
  $comp->{RHUMBA_STYLE}=ESQUE;
  $comp->{CHACHA_STYLE}=ESQUE;
  $comp->{BOLERO_STYLE}=ESQUE;
  $comp->{SWING_STYLE}=ESQUE;
  $comp->{MAMBO_STYLE}=ESQUE;
  $comp->{SAMBA_STYLE}=ESQUE;
  $comp->{RUMBA_STYLE}=ESQUE;
  $comp->{PASO_STYLE}=ESQUE;
  $comp->{JIVE_STYLE}=ESQUE;
  $comp->{WALTZ_STYLE}=MODERN;
  $comp->{TANGO_STYLE}=MODERN;
  $comp->{FOXTROT_STYLE}=MODERN;
  $comp->{VIENNESE_STYLE}=MODERN;
  $comp->{QUICKSTEP_STYLE}=MODERN;

  bless($comp, $class);
  return($comp);
}
  
sub process_master {
  my ($dancetype, $level, $continent, $name, $rest, @names, @master);

# They could've said MASTER={ or MASTER=^J{DANCE
  if (/Dance/) {
    s/\{//;
  } else {
    $_=<IN>;
  }

# I love infinite loops.  Don't sneeze.
  while(1) {
# Skip comments.
    if (/^#/) {
      $_=<IN>;
      next;
    }
# Skip blank lines.
    if (/^\s*$/) {
      $_=<IN>;
      next;
    }
# We're outta here when we see the close-brace.
    last if /\}/;

# Rip off the trailing ) and a comma, if there is one.
    s/\),{0,1}\s*$//;
# Get rid of any whitespace.
    s/\s+//g;

# At this point, we have something like
#     SingleDance(OPEN,INTERNATIONAL,WALTZ
# since we've already ripped off the trailing )
    ($dancetype, $rest)=split('\(', $_);
    if ($dancetype eq "SingleDance") {
      ($level, $continent, $name)=split(',', $rest);
      push(@master, SingleDance->new($level, $continent, $name));
#      $dance=SingleDance->new2($level, $continent, $name);
#      push(@master, $dance);
    } elsif ($dancetype eq "MultiDance") {
      ($level, $continent, @names)=split(',', $rest);
      if ($#names==1) {
	push(@master, MultiDance->new2($level, $continent, $names[0],
				      $names[1]));
      } elsif ($#names==2) {
	push(@master, MultiDance->new3($level, $continent, $names[0],
				       $names[1], $names[2]));
      } elsif ($#names==3) {
	push(@master, MultiDance->new4($level, $continent, $names[0],
				       $names[1], $names[2], $names[3]));
      } elsif ($#names==4) {
	push(@master, MultiDance->new5($level, $continent, $names[0],
				       $names[1], $names[2], $names[3],
				       $names[4]));
      } else {
	die "Bad description in Constants file.\n";
      }
    } else {
      die "Bad *Dance designation in the Constants file ($dancetype).\n";
    }
    $_=<IN>;
  }

  return(\@master);
}

# Not used anymore, I don't think.
sub process_alphabet {
  my (@alpha, $crap, $data, @new, $i, $keeplooping);

  $_=$_[0];
  s/^.+\{//;
  $keeplooping=1;
  while($keeplooping) {
    $keeplooping=0 if /\}/;
    s/\'|\s//g;
    s/^\{//;
    s/\}$//;
    @new=split(',', $_);
    while ($data=shift(@new)) {
      push(@alpha, $data) if ($data ne "");
    }
    $_=<IN>;
  }
  return(\@alpha);
}

sub process_schools {
  my @schools;
  my $keeplooping=1;

  $_=$_[0];
# Get rid of any leading whitespace, and also the {...
  s/^\s*\{//;
# Or, get rid of any leading whitespace, and also the "
# Why do we do it like this?  Weird.
  s/^\s*\"//;

# Get rid of the trailing ", and the comma if there is one
  s/\",{0,1}\s*$//;

  push(@schools, $_);
  while($keeplooping) {
    $_=<IN>;
    $keeplooping=0 if /\}/;
    s/^\s*\"//;
    s/\",{0,1}\s*$//;
    s/\"{0,1}\}\s*$//;
    push(@schools, $_) if ($_ ne "");
  }
  return(\@schools);
}

sub getLevelAbbrev {
  my $level=$_[0];
  if ($level eq NEWCOMER) {
    return($comp->{NEWCOMER_ABBREV});
  } elsif ($level eq BEGINNER) {
    return($comp->{BEGINNER_ABBREV});
  } elsif ($level eq INTERMEDIATE) {
    return($comp->{INTERMEDIATE_ABBREV});
  } elsif ($level eq ADVANCED) {
    return($comp->{ADVANCED_ABBREV});
  } elsif ($level eq OPEN) {
    return($comp->{OPEN_ABBREV});
  } elsif ($level eq PRE_BRONZE) {
    return($comp->{PRE_BRONZE_ABBREV});
  } elsif ($level eq BRONZE) {
    return($comp->{BRONZE_ABBREV});
  } elsif ($level eq SILVER) {
    return($comp->{SILVER_ABBREV});
  } elsif ($level eq GOLD) {
    return($comp->{GOLD_ABBREV});
  } elsif ($level eq NOVICE) {
    return($comp->{NOVICE_ABBREV});
  } elsif ($level eq PRE_CHAMP) {
    return($comp->{PRE_CHAMP_ABBREV});
  } elsif ($level eq CHAMP) {
    return($comp->{CHAMP_ABBREV});
  } # elsif ($level eq TEAMMATCH) {
  return($comp->{TEAMMATCH_ABBREV});
}

sub getDanceAbbrev {
  my $name=$_[0];
  if ($name eq RHUMBA) {
    return($comp->{RHUMBA_ABBREV});
  } elsif ($name eq CHACHA) {
    return($comp->{CHACHA_ABBREV});
  } elsif ($name eq BOLERO) {
    return($comp->{BOLERO_ABBREV});
  } elsif ($name eq SWING) {
    return($comp->{SWING_ABBREV});
  } elsif ($name eq MAMBO) {
    return($comp->{MAMBO_ABBREV});
  } elsif ($name eq SAMBA) {
    return($comp->{SAMBA_ABBREV});
  } elsif ($name eq RUMBA) {
    return($comp->{RUMBA_ABBREV});
  } elsif ($name eq PASO) {
    return($comp->{PASO_ABBREV});
  } elsif ($name eq JIVE) {
    return($comp->{JIVE_ABBREV});
  } elsif ($name eq WALTZ) {
    return($comp->{WALTZ_ABBREV});
  } elsif ($name eq TANGO) {
    return($comp->{TANGO_ABBREV});
  } elsif ($name eq FOXTROT) {
    return($comp->{FOXTROT_ABBREV});
  } elsif ($name eq VIENNESE) {
    return($comp->{VIENNESE_ABBREV});
  } elsif ($name eq QUICKSTEP) {
    return($comp->{QUICKSTEP_ABBREV});
  } else {
    return($comp->{name});
  }
}

sub getStyle {
  my ($name, $level)=@_;
  if ($level eq TEAMMATCH) {
    return(FUN_STYLE);
  }
  if ($name eq RHUMBA) {
    return(ESQUE);
  } elsif ($name eq CHACHA) {
    return(ESQUE);
  } elsif ($name eq BOLERO) {
    return(ESQUE);
  } elsif ($name eq SWING) {
    return(ESQUE);
  } elsif ($name eq MAMBO) {
    return(ESQUE);
  } elsif ($name eq SAMBA) {
    return(ESQUE);
  } elsif ($name eq RUMBA) {
    return(ESQUE);
  } elsif ($name eq PASO) {
    return(ESQUE);
  } elsif ($name eq JIVE) {
    return(ESQUE);
  } elsif ($name eq WALTZ) {
    return(MODERN);
  } elsif ($name eq TANGO) {
    return(MODERN);
  } elsif ($name eq FOXTROT) {
    return(MODERN);
  } elsif ($name eq VIENNESE) {
    return(MODERN);
  } elsif ($name eq QUICKSTEP) {
    return(MODERN);
  } else {
    return(FUN_STYLE);
  }
}

1;
