package org.opengroupware.jope.eoaccess;


/*
 * EORelationship
 * 
 * TODO: complete me
 */
public class EORelationship extends EOProperty {

  protected String   name;
  protected EOEntity entity;
  protected EOEntity destinationEntity;
  protected String   destinationEntityName;
  protected EOJoin[] joins;
  protected int      joinSemantic;
  protected boolean  isToMany;
  
  /* construction */
  
  public EORelationship
    (String _name, boolean _isToMany, EOEntity _src, String _dest,
     EOJoin[] _joins)
  {
    this.name                  = _name;
    this.entity                = _src;
    this.destinationEntityName = _dest;
    this.joins                 = _joins;
    this.isToMany              = _isToMany;
  }
  
  /* accessors */
  
  public String name() {
    return this.name;
  }
  public boolean isToMany() {
    return this.isToMany;
  }
 
  public EOEntity entity() {
    return this.entity;
  }
  
  public EOEntity destinationEntity() {
    return this.destinationEntity;
  }
  
  public EOJoin[] joins() {
    return this.joins;
  }
  
  public int joinSemantic() {
    return this.joinSemantic;
  }
  
  public boolean isCompound() {
    if (this.joins == null) return false;
    return this.joins.length > 1;
  }

  public boolean isFlattened() {
    return false; /* we do not support flattened attributes yet */
  }
  public String relationshipPath() {
    return null; /* this is for flattened properties */
  }
  
  public boolean referencesProperty(Object _property) {
    // TODO: look into data-path for flattened relationships
    if (_property == null)
      return false;
    
    if (this.joins != null) {
      for (int i = 0; i < this.joins.length; i++) {
        if (this.joins[i].referencesProperty(_property))
          return true;
      }
    }
    return false;
  }

  public boolean isConnected() {
    return this.destinationEntity != null;
  }
  public void connectRelationshipsInModel(EOModel _model, EOEntity _entity) {
    if (this.entity == null)
      this.entity = _entity;
    
    if (this.destinationEntityName == null)
      return;
    
    this.destinationEntity = _model.entityNamed(this.destinationEntityName);
    
    if (this.joins != null) {
      for (int i = 0; i < this.joins.length; i++)
        this.joins[i].connectToEntities(this.entity, this.destinationEntity);
    }
  }
  
  /* patterns */
  
  public boolean isPatternRelationship() {
    return false;
  }
  
  /* names */
  
  public void beautifyNames() {
    // TODO
  }
  
  /* constants */
  
  static final int FullOuterJoin  = 1;
  static final int InnerJoin      = 2;
  static final int LeftOuterJoin  = 3;
  static final int RightOuterJoin = 4;
  
  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    super.appendAttributesToDescription(_d);

    if (this.isPatternRelationship())
      _d.append(" pattern");
    
    if (this.name != null) _d.append(" name=" + this.name);
  }
}
