package w3c.wai.parser.html4.struct.table;
import java.util.Vector;
import java.util.Enumeration;
import java.io.*;

public class Cell {
  static final int NOTHING=-1;
  static final int TH=0;
  static final int TD=1;
  static final int SPECIAL=2;
  static final int COL=3;
  static final int ROW=4;
  static final int ROWGROUP=5;
  static final int COLGROUP=6;
  static final int SPECIAL_ROW=7;
  static final int THEADER=8;
  static final int TH_SPECIAL=10;
  static final int TD_SPECIAL=11;
  static final int SPECIAL_TH_ROW_COL=12;
  static final int SPECIAL_ROW_COL=13;
  
  private int type;
  private int colspan;
  private int rowspan;
  private Vector value=null;
  private String abbr=null;
  private int scope=-1;
  private String header=null;
  private String id=null;
  
  public Cell(Vector value,
	      int type,
	      int colspan,
	      int rowspan,
	      String abbr,
	      int scope,
	      String header,
	      String id) {
    
    this.value=value;
    this.type=type;
    this.colspan=colspan;
    this.rowspan=rowspan;
    if (abbr!=null && abbr.length()>2 && abbr.charAt(0)=='"' && abbr.charAt(abbr.length()-1)=='"')
      this.abbr=abbr.substring(1,abbr.length()-1);
    else
      this.abbr=abbr;
    this.scope=scope;
    this.header=header;
    this.id=id;
  }
  
  protected void print(Vector v,int nbrPrintable,
		       BufferedWriter fw) 
       throws IOException {

	 if (nbrPrintable>0) {
	   fw.write(Table.cellSeparator);
	   fw.flush();
	 }
	  if (((Vector)v.elementAt(0)).size()!=0 || 
	      ((Vector)v.elementAt(1)).size()!=0) {

	    Enumeration e=((Vector)v.elementAt(0)).elements();
	    while (e.hasMoreElements()) {
	      Cell c=(Cell)e.nextElement();
	      printHeader(c,fw);
	      if (e.hasMoreElements()) {
		fw.write(Table.headerSeparator);
		fw.flush();
	      }
	      else 
		if (((Vector)v.elementAt(1)).size()>0) {
		  fw.write(Table.headerSeparator);
		  fw.flush();
		}
	    }
	    
	    Vector column=(Vector)v.elementAt(1);
	    for (int cpt=0;cpt<(column.size()-1);cpt++) {
	      printHeader((Cell)column.elementAt(cpt),fw);
	      fw.write(Table.headerSeparator);
	      fw.flush();
	    }
	    if (column.size()>0) {
	      printHeader((Cell)column.lastElement(),fw);
	    }
	  }
	  else {
	    fw.write("--NO HEADER-- ");
	    fw.flush();
	  }
	  fw.write(Table.valueSeparator);
	  print(fw);
  }
  
  protected void print(BufferedWriter fw) throws IOException {
    for (int cpt=0;cpt<value.size();cpt++) {
      if (value.elementAt(cpt) instanceof Table) {
	((Table)value.elementAt(cpt)).print();
      }
      else {
	fw.write((String)value.elementAt(cpt));
	fw.flush();
      }
    }
  }
  
  private void printHeader(Cell c /*the header*/,BufferedWriter fw) 
       throws IOException {
	 StringBuffer sb=new StringBuffer();
	 if (c!=null) {
	   if (c.abbr!=null) {
	     fw.write(c.abbr);
	     fw.flush();
	   }
	   else 
	     c.printHeader(fw);
	 }
  }
  
  private void printHeader(BufferedWriter fw) throws IOException {
    StringBuffer sb=new StringBuffer();
    
    for (int cpt=0;cpt<value.size();cpt++) {
      if (value.elementAt(cpt) instanceof Table) {
	String summary=((Table)value.elementAt(cpt)).getSummary();
	String caption=((Table)value.elementAt(cpt)).getCaption().getValue();
	if (summary==null) {
	  if (caption!=null) {
	    fw.write(caption+" ");
	    fw.flush();
	  }
	}
	else {
	  fw.write(summary+" ");
	  fw.flush();
	}
      }
      else {
	fw.write((String)value.elementAt(cpt)+" ");
	fw.flush();
      }
    }
  }
  
  public String getAbbr() {
    return abbr;
  }
  
  public int getColspan() {
    return colspan;
  }
  
  public String getHeader() {
    return header;
  }
  
  public String getId() {
    return id;
  }
  
  
  public int getRowspan() {
    return rowspan;
  }
  
  public int getType() {
    return type;
  }
  
  protected void setType(int type) {
    this.type=type;
  }


  public boolean isPrintable() {
    return !isAnHeader() && type!=TD_SPECIAL &&
      type!=SPECIAL_ROW_COL && type!=THEADER /*&& type!=SPECIAL*/;
  }

  public boolean isPrintableDeepest() {
    return !isAnHeader() && type!=THEADER /*&& type!=SPECIAL*/;
  }

  public boolean isAnHeader() {
    return type==TH || type==SPECIAL_ROW || scope==COL || scope==ROW ||
      scope==ROWGROUP || scope==COLGROUP || type==TH_SPECIAL || 
      type==SPECIAL_TH_ROW_COL;
  }
  
  public boolean isSpecialHeader() {
    return type==SPECIAL_ROW || type==TH_SPECIAL ||
      type==SPECIAL_TH_ROW_COL;
  }

  public boolean isSpecialRowHeader() {
    return type==SPECIAL_ROW || type==SPECIAL_TH_ROW_COL;
  }

  public boolean isSpecialRow() {
    return isSpecialRowHeader() || type==SPECIAL || 
      type==SPECIAL_ROW_COL;
  }

  public boolean isTHeader() {
    return type==THEADER;
  }

  protected void printLayout(BufferedWriter fw) throws IOException {
    if (type!=SPECIAL && type!=TD_SPECIAL && 
	type!=SPECIAL_ROW_COL) {
      for (int cpt=0;cpt<value.size();cpt++) {
	if (value.elementAt(cpt) instanceof Table) {
	  ((Table)value.elementAt(cpt)).print();
	}
	else {
	  fw.write((String)value.elementAt(cpt)+"\n");
	  fw.flush();
	}
      }
    }
  }

  public Cell myClone() {
      return new Cell(value,
		      (type==TH?SPECIAL_ROW:
		       (type==TH_SPECIAL?SPECIAL_TH_ROW_COL:
			(type==TD?SPECIAL:
			 (type==THEADER?THEADER:
			  SPECIAL_ROW_COL)))),
		      colspan,
		      rowspan,
		      abbr,
		      scope,
		      header,
		      id);
  }
  
  public int getScope() {
    return scope;
  }
  
  public void setHeader() {
    type=THEADER;
    scope=(colspan>1?COLGROUP:COL);
  }

  public Vector getValue() {
    return value;
  }

  public boolean isNotEmpty() {
    for (int cpt=0;cpt<value.size();cpt++) {
      if (value.elementAt(cpt) instanceof String) {
	String s=(String)value.elementAt(cpt);
	for (int cpt2=0;cpt2<s.length();cpt2++)
	  if (s.charAt(cpt2)!=' ' || 
	      s.charAt(cpt2)!='\t' ||
	      s.charAt(cpt2)!='\n' ||
	      s.charAt(cpt2)!='\r')
	    return true;
      }
      else 
	return true;
    }
    return false;
  }
  
  public boolean isNotEmptyHeader() {
    return isNotEmpty() || abbr!=null;
  }
  
  public String toString() {
    return /*"value: "+value+*/" id= "+id+" headers="+header+" scope:"+scope+" colspan= "+colspan+" rowspan= "+rowspan+" type= "+type+" ---";
  }
  
}



