package hw.hashtable;

/**
 * Hash Table. Koristi se odvojeno ulancavanje
 * (separate chaining).
 * 
 * @author ETF
 *
 */
public class HashTable {
  private HashNode[] table; // hash tabela
  
  private int numOfElem;  // broj kljuceva u hash tabeli
  
  private static int INIT_SIZE = 64;
  
  public HashTable() {
    this(64);
  }
  
  public HashTable(int s) {
    table = new HashNode[s];
  }
  
  public int getNumOfElem() {
    return numOfElem;
  }
  
  
  /**
   * Pretrazivanje hash-a na odredjenu vrednost
   * kljuca.
   * 
   * @return HashNode koji sadrzi kljuc po kome
   * se pretrazivalo ukoliko je kljuc nadjen, null
   * u suprotnom
   */
  public HashNode searchKey(String key) {
    int index = hash(key) % table.length; // upotreba hash metode
    // *** IMPLEMENT ***
    return null;
  }
  
  /** 
   * Brisanje elementa sa vrednoscu kljuca key.
   * print == true ako zelimo da se na izlaz ispisuje poruka pri pokusaju
   * brisanja kljuca koji se ne nalazi u hesu.
   * print == false ako NE zelimo da se na izlaz ispisuje poruka pri pokusaju
   * brisanja kljuca koji se ne nalazi u hesu.
   * 
   * @return Uspesnosti operacije brisanja. true je indikacija uspesnog
   * brisanja kljuca iz hash tabele. false u suprotnom
   */    
  public boolean deleteKey(String key, boolean print) {
    // videti searchKey za upotrebu hash metode
    // *** IMPLEMENT ***
    return false;
  }
  
  /** 
   * Umetanje elementa sa novom vrednoscu kljuca.
   * Argument key je vrednost kljuca koji treba umetnuti.
   * Duplikati kljuceva nisu dozvoljeni.
   * print == true ako zelimo da se na izlaz ispisuje poruka pri pokusaju
   * umetanja vec postojeceg kljuca.
   * print == false ako NE zelimo da se na izlaz ispisuje poruka pri pokusaju
   * umetanja vec postojeceg kljuca.
   *
   * @return true ukoliko je umentanje uspesno, false u suprotnom
   */
  public boolean insertKey(String key, boolean print) {
    // videti searchKey za upotrebu hash metode
    // *** IMPLEMENT ***
    return false;
  }
  
  /** 
   * Umetanje novog elementa node u hes.
   * Element ne sme imati kljuc koji vec postoji u hesu.
   * print == true ako zelimo da se na izlaz ispisuje poruka pri pokusaju
   * umetanja elementa koji sadrzi vec postojeci kljuc.
   * print == false ako NE zelimo da se na izlaz ispisuje poruka pri pokusaju
   * umetanja elementa koji sadrzi vec postojeci kljuc.
   *
   * @return true ukoliko je umetanje uspesno, false u suprotnom
   */
    public boolean insertKey(HashNode node, boolean print) {
      return insertKey(node.getName(), print);
    }
  
  /** 
   * hash funkcija
   */
  private static int hash (String key) {
      /* this algorithm was created for sdbm
       * (a public-domain reimplementation of ndbm) database library.
       * what is included below is the faster version used in gawk.
       */
      int h = 0;
      for (int i=0; i < key.length(); i++) {
          h = key.charAt(i) + (h << 6) + (h << 16) - h;
      }
      return h;  
  }
}
