//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//

#include <cool/String.h>
#include <cool/Vector.h>
#include <cool/Hash_Table.h>
#include <test.h>

DECLARE Vector<int>;
IMPLEMENT Vector<int>;
DECLARE Hash_Table<int,double>;
IMPLEMENT Hash_Table<int,double>;
DECLARE Hash_Table<double,String>;
IMPLEMENT Hash_Table<double,String>;
DECLARE Hash_Table<Vector<int>,String>;
IMPLEMENT Hash_Table<Vector<int>,String>;

extern void test_int_double ();

void test_double_String () {
  String s;
  // get and put pass values by reference.  Cfront creates stack
  // temporaries for these values, which creates too many
  // nesting levels for the Microsoft C compiler.
  static double d1=1, d2=2, d3=3, d4=4, d5=5, d6=6, d7=7, d8=8, d9=9;
  Hash_Table<double,String> h0;
  TEST ("Hash_Table<double,String> h0",h0.get_bucket_count(),3);
  Hash_Table<double,String> h1(20);
  TEST ("Hash_Table<double,String> h1(20)",h1.get_bucket_count(),3);
  Hash_Table<double,String> h2(25);
  TEST ("Hash_Table<double,String> h2(25)",h2.get_bucket_count(),7);
  Hash_Table<double,String> h3(h2);
  TEST ("Hash_Table<double,String> h3(h2)",h3.get_bucket_count(),7);
  TEST ("h2==h3",(h2==h3), TRUE);
  TEST ("h2 == h3", (h2 == h3), TRUE);
  TEST ("h1 == h2", (h1 == h2), TRUE);
  TEST ("h1 != h3", (h1 != h3), FALSE);
  TEST ("h0.put(1.0,String(\"ABCD\"))", h0.put(d1,String("ABCD")),TRUE);
  TEST("h0.get(1.0,s)",(h0.get(d1,s)==TRUE && strcmp(s,"ABCD")==0),TRUE);
  TEST ("h0.length()", h0.length(), 1);
  TEST ("h0.put(2.0,String(\"EFGH\"))", h0.put(d2,String("EFGH")),TRUE);
  TEST("h0.get(2.0,s)",(h0.get(d2,s)==TRUE && strcmp(s,"EFGH")==0),TRUE);
  TEST ("h0.put(3.0,String(\"IJKL\"))", h0.put(d3,String("IJKL")),TRUE);
  TEST("h0.get(3.0,s)",(h0.get(d3,s)==TRUE && strcmp(s,"IJKL")==0),TRUE);
  TEST ("h0.put(4.0,String(\"MNOP\"))", h0.put(d4,String("MNOP")),TRUE);
  TEST("h0.get(4.0,s)",(h0.get(d4,s)==TRUE && strcmp(s,"MNOP")==0),TRUE);
  TEST ("h0.put(5.0,String(\"QRsT\"))", h0.put(d5,String("QRST")),TRUE);
  TEST("h0.get(5.0,s)",(h0.get(d5,s)==TRUE && strcmp(s,"QRST")==0),TRUE);
  TEST ("h0.put(6.0,String(\"UVWX\"))", h0.put(d6,String("UVWX")),TRUE);
  TEST("h0.get(6.0,s)",(h0.get(d6,s)==TRUE && strcmp(s,"UVWX")==0),TRUE);
  // TEST ("h0.get_key(\"QRST\",d)", h0.get_key("QRST",d), TRUE);
  // TEST ("d == 5.0", (d == 5.0), 1);
  TEST ("h0.put(7.0,String(\"YZab\"))", h0.put(d7,String("YZab")),TRUE);
  TEST("h0.get(7.0,s)",(h0.get(d7,s)==TRUE && strcmp(s,"YZab")==0),TRUE);
  TEST ("h0.put(8.0,String(\"cdef\"))", h0.put(d8,String("cdef")),TRUE);
  TEST("h0.get(8.0,s)",(h0.get(d8,s)==TRUE && strcmp(s,"cdef")==0),TRUE);
  TEST ("h0.put(9.0,String(\"ghij\"))", h0.put(d9,String("ghij")),TRUE);
  TEST("h0.get(9.0,s)",(h0.get(d9,s)==TRUE && strcmp(s,"ghij")==0),TRUE);
  TEST ("h0.get_bucket_count()", h0.get_bucket_count(), 3);
  TEST ("h0.length()", h0.length(), 9);
  TEST ("h0.remove(1.0)", h0.remove(1.0), TRUE);
  TEST ("h0.length()", h0.length(), 8);
  TEST ("h1=h0", (h1=h0,(h0==h1)), TRUE);
  h1.resize(30); //  TEST ("h1.resize(30)", h1.resize(30), TRUE);
  TEST("h1.get(7.0,s)",(h1.get(d7,s)==TRUE && strcmp(s,"YZab")==0),TRUE);
  TEST("h1.get(3.0,s)",(h1.get(d3,s)==TRUE && strcmp(s,"IJKL")==0),TRUE);
  TEST("h1.get(9.0,s)",(h1.get(d9,s)==TRUE && strcmp(s,"ghij")==0),TRUE);
  TEST ("h1.get_bucket_count()", h1.get_bucket_count(), 7);
  TEST ("h1.length()", h1.length(), 8);
  TEST ("h0.set_ratio(1.0)", (h0.set_ratio(1.0),1), 1);
  h0.resize(30); //  TEST ("h0.resize(30)", h0.resize(30), TRUE);
  TEST ("h0.get_bucket_count()", h0.get_bucket_count(), 7);
  TEST("h0.get(2.0,s)",(h0.get(d2,s)==TRUE && strcmp(s,"EFGH")==0),TRUE);
  TEST("h0.get(4.0,s)",(h0.get(d4,s)==TRUE && strcmp(s,"MNOP")==0),TRUE);
  TEST("h0.get(6.0,s)",(h0.get(d6,s)==TRUE && strcmp(s,"UVWX")==0),TRUE);
  TEST("h0.get(8.0,s)",(h0.get(d8,s)==TRUE && strcmp(s,"cdef")==0),TRUE);
  h0.resize(60); //  TEST ("h0.resize(60)", h0.resize(60), TRUE);
  TEST ("h0.get_bucket_count()", h0.get_bucket_count(), 19);
  TEST("h0.get(2.0,s)",(h0.get(d2,s)==TRUE && strcmp(s,"EFGH")==0),TRUE);
  TEST("h0.get(4.0,s)",(h0.get(d4,s)==TRUE && strcmp(s,"MNOP")==0),TRUE);
  TEST("h0.get(6.0,s)",(h0.get(d6,s)==TRUE && strcmp(s,"UVWX")==0),TRUE);
  TEST("h0.get(8.0,s)",(h0.get(d8,s)==TRUE && strcmp(s,"cdef")==0),TRUE);
  // TEST ("h0.get_key(\"cdef\",d)", h0.get_key("cdef",d), TRUE);
  // TEST ("d == 8.0", (d == 8.0), 1);
  TEST ("h0.clear()", (h0.clear(), h0.length()), 0);
  TEST ("h1.clear()", (h1.clear(), h1.length()), 0);
}

void test_Vector_int_String () {
  String s;
  String s1("Hello World");
  TEST ("String s1(\"Hello World\")",0,0);
  String s2("Up, up, and away!");
  TEST ("String s2(\"Up, up, and away!\")",0,0);
  Vector<int> v1(5,1);
  TEST ("Vector<int> v1(5,1)",(v1[0]==1 && v1[1]==1 && v1[2]==1 && v1[3]==1 && v1[4]==1),1);
  Vector<int> v2(8);
  TEST ("Vector<int> v2(8)",0,0);
  v2.set_length(8);
  TEST ("v2.set_length(8)", v2.length(), 8);
  for (int i = 0; i < 8; i++)
    v2[i] = i;
  Hash_Table<Vector<int>,String> h1;
  TEST ("Hash_Table<Vector<int>,String> h1",h1.get_bucket_count(),3);
  TEST ("h1.put(v1,s1)", h1.put(v1,s1), TRUE);
  TEST ("h1.get(v1,s)", (h1.get(v1,s)==TRUE && strcmp (s,s1)==0), TRUE);
  TEST ("h1.length()", h1.length(), 1);
  TEST ("h1.put(v2,s2)", h1.put(v2,s2), TRUE);
  TEST ("h1.put(v2,s2) again", h1.put(v2,s2), FALSE);
  TEST ("h1.get(v2,s)", (h1.get(v2,s)==TRUE && strcmp (s,s2)==0), TRUE);
  TEST ("h1.length()", h1.length(), 2);
}

int main (void) {
  START("Hash_Table");
  test_int_double ();
  test_double_String  ();
  test_Vector_int_String ();
  SUMMARY();
  return 0;
}
