// $Id: XobjectSet.java,v 1.7 2000/12/20 06:24:32 msato Exp $
// $RWC_Release: Omni-1.6 $
// $RWC_Copyright:
//  Omni Compiler Software Version 1.5-1.6
//  Copyright (C) 2002 PC Cluster Consortium
//  
//  This software is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License version
//  2.1 published by the Free Software Foundation.
//  
//  Omni Compiler Software Version 1.0-1.4
//  Copyright (C) 1999, 2000, 2001.
//   Tsukuba Research Center, Real World Computing Partnership, Japan.
//  
//  Please check the Copyright and License information in the files named
//  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
//  Software release kit.
//  
//  
//  $
package exc.util;

import exc.object.*;
import java.util.*;

public class XobjectSet implements Set {
  boolean isfull = false;
  Vector v;

  public XobjectSet() { v = new Vector(); }
  public XobjectSet(boolean isfull){ v = new Vector(); this.isfull = isfull; }

  public Enumeration elements() { return v.elements(); }

  public static XobjectSet empty(){  return new XobjectSet();  }
  public static XobjectSet full(){ return new XobjectSet(true); }

  public boolean isFull() { return isfull; }
  public boolean isEmpty() { return !isfull && v.isEmpty(); }

  public void clear(){
    isfull = false;
    v.removeAllElements();
  }

  public void all(){
    isfull = true;
  }

  public void copy(Set set){
    v.removeAllElements();
    if(set == null) return;
    if(set.isFull()){
      isfull = true;
      return;
    }
    for(Enumeration e = ((XobjectSet)set).v.elements(); e.hasMoreElements(); ){
      v.addElement((Xobject)e.nextElement());
    }
  }
    
  public boolean contain(Xobject x){
    if(isfull) return true;
    if(v.contains(x)) return true;
    return false;
  }

  public void add(Xobject x){
    if(isfull) return;
    if(!v.contains(x)) v.addElement(x);
  }
    
  public void add(Set set){
    if(isfull) return;
    if(set == null) return;
    if(set.isFull()){
      isfull = true;
      return;
    }
    for(Enumeration e = ((XobjectSet)set).v.elements();e.hasMoreElements(); ){
      Xobject x = (Xobject)e.nextElement();
      if(!v.contains(x)) v.addElement(x);
    }
  }

  // for intersect
  public void dot(Set set){
    if(isfull){
      copy(set);
      return;
    }
    if(set == null){
      clear();
      return;
    }
    if(set.isFull()) return;
    XobjectSet s = (XobjectSet)set;
    for(Enumeration e = v.elements();e.hasMoreElements(); ){
      Xobject x = (Xobject) e.nextElement();
      if(!s.v.contains(x)) v.removeElement(x);
    }
  }

  public boolean remove(Xobject x){
    if(isfull) fatal("XobjectSet: remove from full set");
    return v.removeElement(x);
  }

  public void remove(Set set){
    if(set == null) return;
    if(isfull) fatal("XobjectSet: remove from full set");
    XobjectSet s = (XobjectSet)set;
    for(Enumeration e = s.v.elements();e.hasMoreElements(); ){
      remove((Xobject)e.nextElement());
    }
  }

  // update with s
  public boolean update(Set set){
    XobjectSet s = (XobjectSet)set;
    if(equals(s)) return false;
    copy(s);
    return true;
  }

  public boolean equals(Set set){
    if(set == null) return false;
    XobjectSet s = (XobjectSet)set;
    for(Enumeration e = s.v.elements();e.hasMoreElements(); ){
      if(!v.contains(e.nextElement())) return false;
    }
    for(Enumeration e = v.elements();e.hasMoreElements(); ){
      if(!s.v.contains(e.nextElement())) return false;
    }
    return true;
  }
    
  // create union set
  public XobjectSet unionSet(XobjectSet s){
    XobjectSet ss = new XobjectSet();
    ss.copy(this);
    ss.add(s);
    return ss;
  }

  // create intersection set
  public XobjectSet intersectSet(XobjectSet s){
    XobjectSet ss = new XobjectSet();
    ss.copy(this);
    ss.dot(s);
    return ss;
  }
  
  public String toString(){
    if(isfull) return "[*Full*]";
    return v.toString();
  }


  void fatal(String msg){
    System.err.println("Fatal error: "+msg);
    Thread.dumpStack();
    System.exit(1);
  }
}


