/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in 
 * compliance with the License.  You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is Protege-2000.
 *
 * The Initial Developer of the Original Code is Stanford University. Portions
 * created by Stanford University are Copyright (C) 2007.  All Rights Reserved.
 *
 * Protege was developed by Stanford Medical Informatics
 * (http://www.smi.stanford.edu) at the Stanford University School of Medicine
 * with support from the National Library of Medicine, the National Science
 * Foundation, and the Defense Advanced Research Projects Agency.  Current
 * information about Protege can be obtained at http://protege.stanford.edu.
 *
 */

 
package edu.stanford.smi.protegex.owl.swrl.bridge.impl;

import edu.stanford.smi.protegex.owl.swrl.bridge.*;
import edu.stanford.smi.protegex.owl.swrl.bridge.exceptions.*;

/**
 ** Class representing argument to built-ins
 */
public class BuiltInArgumentImpl implements BuiltInArgument
{
  // There is an equals methods defined for this class.
  private String variableName, prefixedVariableName;
  private boolean isAVariable;
  private BuiltInArgument builtInResult; // Used to store result of binding for unbound arguments
  private boolean isArgumentUnbound;

  public BuiltInArgumentImpl()
  {
    variableName = null;
    prefixedVariableName = null;
    isAVariable = false;
    builtInResult = null; 
    isArgumentUnbound = false;
  } // ArgumentImpl

  public BuiltInArgumentImpl(String variableName, String prefixedVariableName) 
  {
    this.variableName = variableName;
    this.prefixedVariableName = prefixedVariableName;
    isAVariable = true;
    builtInResult = null; 
    isArgumentUnbound = false;
  } // BuiltInArgumentImpl

  public boolean isVariable() { return isAVariable; }

  public void setVariableName(String variableName, String prefixedVariableName)
  {
    this.variableName = variableName;
    this.prefixedVariableName = prefixedVariableName;
    isAVariable = true;
  } // setVariableName

  public String getVariableName() throws BuiltInException
  {
    if (!isVariable()) throw new BuiltInException("attempt to get variable name of non variable argument '" + this.toString() + "'");
    
    return variableName;
  } // getVariableName

  public String getPrefixedVariableName() throws BuiltInException
  {
    if (!isVariable()) throw new BuiltInException("attempt to get prefixed variable name of non variable argument '" + this.toString() + "'");
    
    return prefixedVariableName;
  } // getPrefixedVariableName

  public void setBuiltInResult(BuiltInArgument builtInResult) throws BuiltInException
  { 
    if (!isUnbound()) throw new BuiltInException("attempt to bind value to bound argument '" + this.toString() + "'");

    this.builtInResult = builtInResult; 
  } // setBuiltInResult

  public BuiltInArgument getBuiltInResult() throws BuiltInException
  { 
    if (!isUnbound()) throw new BuiltInException("attempt to retrieve binding from a non bound argument '" + this.toString() + "'");

    return builtInResult; 
  } // getBuiltInResult

  public void setUnbound() { isArgumentUnbound = true; }
  public boolean isUnbound() { return isArgumentUnbound; }

  public boolean equals(Object obj)
  {
    if(this == obj) return true;
    if((obj == null) || (obj.getClass() != this.getClass())) return false;
    BuiltInArgumentImpl impl = (BuiltInArgumentImpl)obj;
    return (((variableName == impl.variableName || variableName != null && variableName.equals(impl.variableName))) &&
            ((prefixedVariableName == impl.prefixedVariableName || prefixedVariableName != null && prefixedVariableName.equals(impl.prefixedVariableName))) &&
            (isAVariable == impl.isAVariable) &&
            (isArgumentUnbound == impl.isArgumentUnbound) &&
            ((builtInResult == impl.builtInResult) || (builtInResult != null && builtInResult.equals(impl.builtInResult))));
  } // equals

  public int hashCode()
  {
    int hash = 78;
    hash = hash + (null == variableName ? 0 : variableName.hashCode());
    hash = hash + (null == prefixedVariableName ? 0 : prefixedVariableName.hashCode());
    hash = hash + (isAVariable ? 0 : 1);
    hash = hash + (null == builtInResult ? 0 : builtInResult.hashCode());
    hash = hash + (isArgumentUnbound ? 0 : 1);
    return hash;
  } // hashCode

} // BuiltInArgumentImpl
