package commons.collections;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import commons.collections.interfaces.Sized;
public class ListOfSentences implements Sized
{

List<List<String>> lists = new ArrayList<List<String>>();

public ListOfSentences()
{
   lists.add(new ArrayList<String>());
}

public List<List<String>> getLists ()
{
   return lists;
}

public int size ()
{
   return lists.size();
}

public long signs ()
{
   long s = 0;
   for (List<String> l : lists)
   {
      for (String t : l)
         s += t.length();
      break;
   }
   return s * lists.size();
}


/**
 * remove term from all lists in list, and remove empty lists.
 */
public synchronized void removeEmptyLists()
{
   for(int a = lists.size() - 1; a >= 0; a--)
   {
      List<String> l = lists.get(a);
      if(l.size() == 0)
         lists.remove(a);
   }
}


public void setLists (List<List<String>> lists)
{
   this.lists = lists;
}

private List<String> lastList ()
{
   int s = size();
   if (s == 0) nextList();
   return lists.get(s - 1);
}

public void addTerm (String term)
{
   lastList().add(term);
}

public void nextList ()
{
   lists.add(new ArrayList<String>());
}

public void nextList (List<String> list)
{
   lists.add(list);
}

public int terms ()
{
   int x = 0;
   for (List<String> l : lists)
      x += l.size();
   return x;
}

public Iterator<List<String>> iterator ()
{
   return lists.iterator();
}

/**
 * slow (must iterate and copy), returns a set of all terms, not sorted.
 */
public List<String> getUniqueWordIndex ()
{
   Set<String> done = new HashSet<String>();
   List<String> u = new ArrayList<String>();
   for (List<String> l : lists)
   {
      for (String t : l)
      {
         if (!done.contains(t))
         {
            u.add(t);
            done.add(t);
         }
      }
   }
   return u;
}

/**
 */
public synchronized Iterator<String> uniqueWordIterator ()
{
   return new Iterator<String>()
   {

      Set<String>  done         = new HashSet<String>();
      List<String> currentList  = null;
      String       currentTerm  = null;
      int          listNdx      = 0;
      int          termNdx      = 0;
      final int    listCount    = size();
      int          currListSize = 0;

      public boolean hasNext ()
      {
         do
         {
            if (currentList == null)
            {
               termNdx = 0;
               currentList = lists.get(listNdx++);
               currListSize = currentList.size();
            }
            while (termNdx < currListSize)
            {
               currentTerm = currentList.get(termNdx++);
               if (!done.contains(currentTerm)) return true;
            }
            currentList = null;
         } while (listNdx < listCount);
         return false;
      }

      public String next ()
      {
         done.add(currentTerm);
         return currentTerm;
      }

      public void remove ()
      {}
   };
}

public List<String> getList (int ndx)
{
   try
   {
      return lists.get(ndx);
   }
   catch (Exception e)
   {
      return null;
   }
}

/**
 * remove term from all lists in list, and remove empty lists.
 */
public synchronized void remove (String term)
{
   for (int a = lists.size() - 1; a >= 0; a--)
   {
      List<String> l = lists.get(a);
      for (int i = l.size() - 1; i >= 0; i--)
         if (l.get(i).equals(term)) l.remove(i);
      if (l.size() == 0) lists.remove(a);
   }
}

/**
 * remove term from all lists in list, and remove empty lists.
 */
public synchronized void replace (String term, String termNew)
{
   for (int a = lists.size() - 1; a >= 0; a--)
   {
      List<String> l = lists.get(a);
      for (int i = l.size() - 1; i >= 0; i--)
         if (l.get(i).equals(term)) l.set(i, termNew);
   }
}

public String toString ()
{
   StringBuilder s = new StringBuilder();
   s.append(getClass().getSimpleName());
   s.append("{");
   s.append(size());
   s.append(", ");
   s.append(signs());
   s.append("}");
   return s.toString();
}

public String report ()
{
   StringBuilder s = new StringBuilder();
   for (List<String> l : lists)
   {
      boolean ft = true;
      for (String t : l)
      {
         if (ft) ft = !ft;
         else s.append(", ");
         s.append(t);
      }
      s.append(".\n");
   }
   return s.toString();
}
}
