using System;
using System.Runtime.InteropServices;
 
/* ----------------------------------------------------------------------------
 * This file was automatically generated by SWIG (http://www.swig.org).
 * Version 2.0.4
 *
 * Do not make changes to this file unless you know what you are doing--modify
 * the SWIG interface file instead.
 * ----------------------------------------------------------------------------- */

namespace libsbmlcs {

 using System;
 using System.Runtime.InteropServices;

/** 
 * @sbmlpackage{core}
 *
@htmlinclude pkg-marker-core.html A user-defined function in an SBML model.
 *
 * The FunctionDefinition structure associates an identifier with a
 * function definition.  This identifier can then be used as the function
 * called in subsequent MathML content elsewhere in an SBML model.
 * 
 * FunctionDefinition has one required attribute, 'id', to give the
 * function a unique identifier by which other parts of an SBML model
 * definition can refer to it.  A FunctionDefinition instance can also have
 * an optional 'name' attribute of type @c string.  Identifiers and names
 * must be used according to the guidelines described in the %SBML
 * specification (e.g., Section 3.3 in the Level 2 Version 4
 * specification).
 * 
 * FunctionDefinition has a required 'math' subelement containing a MathML
 * expression defining the function body.  The content of this element can
 * only be a MathML 'lambda' element.  The 'lambda' element must begin with
 * zero or more 'bvar' elements, followed by any other of the elements in
 * the MathML subset allowed in SBML Level 2 @em except 'lambda' (i.e., a
 * 'lambda' element cannot contain another 'lambda' element).  This is the
 * only place in SBML where a 'lambda' element can be used.  The function
 * defined by a FunctionDefinition is only available for use in other
 * MathML elements that @em follow the FunctionDefinition definition in the
 * model.  (These restrictions prevent recursive and mutually-recursive
 * functions from being expressed.)
 *
 * A further restriction on the content of 'math' is that it cannot contain
 * references to variables other than the variables declared to the
 * 'lambda' itself.  That is, the contents of MathML 'ci' elements inside
 * the body of the 'lambda' can only be the variables declared by its
 * 'bvar' elements, or the identifiers of other FunctionDefinition
 * instances in the model.  This means must be written so that all
 * variables or parameters used in the MathML content are passed to them
 * via their function parameters.  In SBML Level&nbsp;2, this restriction
 * applies also to the MathML @c csymbol elements for @em time and @em
 * delay; in SBML Level&nbsp;3, it additionally applies to the @c csymbol
 * element for @em avogadro.
 *
 * @note Function definitions (also informally known as user-defined
 * functions) were introduced in SBML Level 2.  They have purposefully
 * limited capabilities.  A function cannot reference parameters or other
 * model quantities outside of itself; values must be passed as parameters
 * to the function.  Moreover, recursive and mutually-recursive functions
 * are not permitted.  The purpose of these limitations is to balance power
 * against complexity of implementation.  With the restrictions as they
 * are, function definitions could be implemented as textual
 * substitutions---they are simply macros.  Software implementations
 * therefore do not need the full function-definition machinery typically
 * associated with programming languages.
 * <br><br>
 * Another important point to note is FunctionDefinition does not
 * have a separate attribute for defining the units of the value returned
 * by the function.  The units associated with the function's return value,
 * when the function is called from within MathML expressions elsewhere in
 * SBML, are simply the overall units of the expression in
 * FunctionDefinition's 'math' subelement when applied to the arguments
 * supplied in the call to the function.  Ascertaining these units requires
 * performing dimensional analysis on the expression.  (Readers may wonder
 * why there is no attribute.  The reason is that having a separate
 * attribute for declaring the units would not only be redundant, but also
 * lead to the potential for having conflicting information.  In the case
 * of a conflict between the declared units and those of the value actually
 * returned by the function, the only logical resolution rule would be to
 * assume that the correct units are those of the expression anyway.)
 * 
 * 
 *
 */

public class FunctionDefinition : SBase {
	private HandleRef swigCPtr;
	
	internal FunctionDefinition(IntPtr cPtr, bool cMemoryOwn) : base(libsbmlPINVOKE.FunctionDefinition_SWIGUpcast(cPtr), cMemoryOwn)
	{
		//super(libsbmlPINVOKE.FunctionDefinitionUpcast(cPtr), cMemoryOwn);
		swigCPtr = new HandleRef(this, cPtr);
	}
	
	internal static HandleRef getCPtr(FunctionDefinition obj)
	{
		return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
	}
	
	internal static HandleRef getCPtrAndDisown (FunctionDefinition obj)
	{
		HandleRef ptr = new HandleRef(null, IntPtr.Zero);
		
		if (obj != null)
		{
			ptr             = obj.swigCPtr;
			obj.swigCMemOwn = false;
		}
		
		return ptr;
	}

  ~FunctionDefinition() {
    Dispose();
  }

  public override void Dispose() {
    lock(this) {
      if (swigCPtr.Handle != IntPtr.Zero) {
        if (swigCMemOwn) {
          swigCMemOwn = false;
          libsbmlPINVOKE.delete_FunctionDefinition(swigCPtr);
        }
        swigCPtr = new HandleRef(null, IntPtr.Zero);
      }
      GC.SuppressFinalize(this);
      base.Dispose();
    }
  }

  
/**
   * Creates a new FunctionDefinition using the given SBML @p level and @p version
   * values.
   *
   * @param level a long integer, the SBML Level to assign to this FunctionDefinition
   *
   * @param version a long integer, the SBML Version to assign to this
   * FunctionDefinition
   *
   *
 * @throws SBMLConstructorException
 * Thrown if the given @p level and @p version combination are invalid
 * or if this object is incompatible with the given level and version.
 *
 *
   *
   *
 * @note Attempting to add an object to an SBMLDocument having a different
 * combination of SBML Level, Version and XML namespaces than the object
 * itself will result in an error at the time a caller attempts to make the
 * addition.  A parent object must have compatible Level, Version and XML
 * namespaces.  (Strictly speaking, a parent may also have more XML
 * namespaces than a child, but the reverse is not permitted.)  The
 * restriction is necessary to ensure that an SBML model has a consistent
 * overall structure.  This requires callers to manage their objects
 * carefully, but the benefit is increased flexibility in how models can be
 * created by permitting callers to create objects bottom-up if desired.  In
 * situations where objects are not yet attached to parents (e.g.,
 * SBMLDocument), knowledge of the intented SBML Level and Version help
 * libSBML determine such things as whether it is valid to assign a
 * particular value to an attribute.
 *
 *
   */ public
 FunctionDefinition(long level, long version) : this(libsbmlPINVOKE.new_FunctionDefinition__SWIG_0(level, version), true) {
    if (libsbmlPINVOKE.SWIGPendingException.Pending) throw libsbmlPINVOKE.SWIGPendingException.Retrieve();
  }

  
/**
   * Creates a new FunctionDefinition using the given SBMLNamespaces object
   * @p sbmlns.
   *
   *
 * 
 * The SBMLNamespaces object encapsulates SBML Level/Version/namespaces
 * information.  It is used to communicate the SBML Level, Version, and (in
 * Level&nbsp;3) packages used in addition to SBML Level&nbsp;3 Core.  A
 * common approach to using libSBML's SBMLNamespaces facilities is to create an
 * SBMLNamespaces object somewhere in a program once, then hand that object
 * as needed to object constructors that accept SBMLNamespaces as arguments.
 *
 * 
   *
   * @param sbmlns an SBMLNamespaces object.
   *
   *
 * @throws SBMLConstructorException
 * Thrown if the given @p sbmlns is inconsistent or incompatible
 * with this object.
 *
 *
   *
   *
 * @note Attempting to add an object to an SBMLDocument having a different
 * combination of SBML Level, Version and XML namespaces than the object
 * itself will result in an error at the time a caller attempts to make the
 * addition.  A parent object must have compatible Level, Version and XML
 * namespaces.  (Strictly speaking, a parent may also have more XML
 * namespaces than a child, but the reverse is not permitted.)  The
 * restriction is necessary to ensure that an SBML model has a consistent
 * overall structure.  This requires callers to manage their objects
 * carefully, but the benefit is increased flexibility in how models can be
 * created by permitting callers to create objects bottom-up if desired.  In
 * situations where objects are not yet attached to parents (e.g.,
 * SBMLDocument), knowledge of the intented SBML Level and Version help
 * libSBML determine such things as whether it is valid to assign a
 * particular value to an attribute.
 *
 *
   */ public
 FunctionDefinition(SBMLNamespaces sbmlns) : this(libsbmlPINVOKE.new_FunctionDefinition__SWIG_1(SBMLNamespaces.getCPtr(sbmlns)), true) {
    if (libsbmlPINVOKE.SWIGPendingException.Pending) throw libsbmlPINVOKE.SWIGPendingException.Retrieve();
  }

  
/**
   * Copy constructor; creates a copy of this FunctionDefinition.
   *
   * @param orig the object to copy.
   */ public
 FunctionDefinition(FunctionDefinition orig) : this(libsbmlPINVOKE.new_FunctionDefinition__SWIG_2(FunctionDefinition.getCPtr(orig)), true) {
    if (libsbmlPINVOKE.SWIGPendingException.Pending) throw libsbmlPINVOKE.SWIGPendingException.Retrieve();
  }

  
/**
   * Creates and returns a deep copy of this FunctionDefinition object.
   *
   * @return the (deep) copy of this FunctionDefinition object.
   */ public new
 FunctionDefinition clone() {
    IntPtr cPtr = libsbmlPINVOKE.FunctionDefinition_clone(swigCPtr);
    FunctionDefinition ret = (cPtr == IntPtr.Zero) ? null : new FunctionDefinition(cPtr, true);
    return ret;
  }

  
/**
   * Returns the value of the 'id' attribute of this FunctionDefinition.
   * 
   * @return the id of this FunctionDefinition.
   */ public new
 string getId() {
    string ret = libsbmlPINVOKE.FunctionDefinition_getId(swigCPtr);
    return ret;
  }

  
/**
   * Returns the value of the 'name' attribute of this FunctionDefinition.
   * 
   * @return the name of this FunctionDefinition.
   */ public new
 string getName() {
    string ret = libsbmlPINVOKE.FunctionDefinition_getName(swigCPtr);
    return ret;
  }

  
/**
   * Get the mathematical formula of this FunctionDefinition.
   *
   * @return an ASTNode, the value of the 'math' subelement of this
   * FunctionDefinition
   */ public
 ASTNode getMath() {
    IntPtr cPtr = libsbmlPINVOKE.FunctionDefinition_getMath(swigCPtr);
    ASTNode ret = (cPtr == IntPtr.Zero) ? null : new ASTNode(cPtr, false);
    return ret;
  }

  
/**
   * Predicate returning @c true if this
   * FunctionDefinition's 'id' attribute is set.
   *
   * @return @c true if the 'id' attribute of this FunctionDefinition is
   * set, @c false otherwise.
   */ public new
 bool isSetId() {
    bool ret = libsbmlPINVOKE.FunctionDefinition_isSetId(swigCPtr);
    return ret;
  }

  
/**
   * Predicate returning @c true if this
   * FunctionDefinition's 'name' attribute is set.
   *
   * @return @c true if the 'name' attribute of this FunctionDefinition is
   * set, @c false otherwise.
   */ public new
 bool isSetName() {
    bool ret = libsbmlPINVOKE.FunctionDefinition_isSetName(swigCPtr);
    return ret;
  }

  
/**
   * Predicate returning @c true if this
   * FunctionDefinition's 'math' subelement contains a value.
   * 
   * @return @c true if the 'math' for this FunctionDefinition is set,
   * @c false otherwise.
   */ public
 bool isSetMath() {
    bool ret = libsbmlPINVOKE.FunctionDefinition_isSetMath(swigCPtr);
    return ret;
  }

  
/**
   * Sets the value of the 'id' attribute of this FunctionDefinition.
   *
   * The string @p sid is copied.
   *
   *
 * 
 * SBML has strict requirements for the syntax of identifiers, that is, the
 * values of the 'id' attribute present on most types of SBML objects.
 * The following is a summary of the definition of the SBML identifier type
 * <code>SId</code>, which defines the permitted syntax of identifiers.  We
 * express the syntax using an extended form of BNF notation:
 * <pre style='margin-left: 2em; border: none; font-weight: bold; font-size: 13px; color: black'>
 * letter ::= 'a'..'z','A'..'Z'
 * digit  ::= '0'..'9'
 * idChar ::= letter | digit | '_'
 * SId    ::= ( letter | '_' ) idChar*</pre>
 * The characters <code>(</code> and <code>)</code> are used for grouping, the
 * character <code>*</code> 'zero or more times', and the character
 * <code>|</code> indicates logical 'or'.  The equality of SBML identifiers is
 * determined by an exact character sequence match; i.e., comparisons must be
 * performed in a case-sensitive manner.  In addition, there are a few
 * conditions for the uniqueness of identifiers in an SBML model.  Please
 * consult the SBML specifications for the exact details of the uniqueness
 * requirements.
 *
 *
   *
   * @param sid the string to use as the identifier of this FunctionDefinition
   *
   *
 * @return integer value indicating success/failure of the
 * function.  @if clike The value is drawn from the
 * enumeration #OperationReturnValues_t. @endif The possible values
 * returned by this function are:
 * @li @link libsbml#LIBSBML_OPERATION_SUCCESS LIBSBML_OPERATION_SUCCESS@endlink
   * @li @link libsbml#LIBSBML_INVALID_ATTRIBUTE_VALUE LIBSBML_INVALID_ATTRIBUTE_VALUE@endlink
   */ public new
 int setId(string sid) {
    int ret = libsbmlPINVOKE.FunctionDefinition_setId(swigCPtr, sid);
    if (libsbmlPINVOKE.SWIGPendingException.Pending) throw libsbmlPINVOKE.SWIGPendingException.Retrieve();
    return ret;
  }

  
/**
   * Sets the value of the 'name' attribute of this FunctionDefinition.
   *
   * The string in @p name is copied.
   *
   * @param name the new name for the FunctionDefinition
   *
   *
 * @return integer value indicating success/failure of the
 * function.  @if clike The value is drawn from the
 * enumeration #OperationReturnValues_t. @endif The possible values
 * returned by this function are:
 * @li @link libsbml#LIBSBML_OPERATION_SUCCESS LIBSBML_OPERATION_SUCCESS@endlink
   * @li @link libsbml#LIBSBML_INVALID_ATTRIBUTE_VALUE LIBSBML_INVALID_ATTRIBUTE_VALUE@endlink
   */ public new
 int setName(string name) {
    int ret = libsbmlPINVOKE.FunctionDefinition_setName(swigCPtr, name);
    if (libsbmlPINVOKE.SWIGPendingException.Pending) throw libsbmlPINVOKE.SWIGPendingException.Retrieve();
    return ret;
  }

  
/**
   * Sets the 'math' subelement of this FunctionDefinition to the Abstract
   * Syntax Tree given in @p math.
   *
   * @param math an AST containing the mathematical expression to
   * be used as the formula for this FunctionDefinition.
   *
   *
 * @return integer value indicating success/failure of the
 * function.  @if clike The value is drawn from the
 * enumeration #OperationReturnValues_t. @endif The possible values
 * returned by this function are:
 * @li @link libsbml#LIBSBML_OPERATION_SUCCESS LIBSBML_OPERATION_SUCCESS@endlink
   * @li @link libsbml#LIBSBML_INVALID_OBJECT LIBSBML_INVALID_OBJECT@endlink
   */ public
 int setMath(ASTNode math) {
    int ret = libsbmlPINVOKE.FunctionDefinition_setMath(swigCPtr, ASTNode.getCPtr(math));
    return ret;
  }

  
/**
   * Unsets the value of the 'name' attribute of this FunctionDefinition.
   *
   *
 * @return integer value indicating success/failure of the
 * function.  @if clike The value is drawn from the
 * enumeration #OperationReturnValues_t. @endif The possible values
 * returned by this function are:
 * @li @link libsbml#LIBSBML_OPERATION_SUCCESS LIBSBML_OPERATION_SUCCESS@endlink
   * @li @link libsbml#LIBSBML_OPERATION_FAILED LIBSBML_OPERATION_FAILED@endlink
   */ public new
 int unsetName() {
    int ret = libsbmlPINVOKE.FunctionDefinition_unsetName(swigCPtr);
    return ret;
  }

  
/**
   * Get the <code>n</code>th argument to this function.
   *
   * Callers should first find out the number of arguments to the function
   * by calling getNumArguments().
   *
   * @param n an integer index for the argument sought.
   * 
   * @return the nth argument (bound variable) passed to this
   * FunctionDefinition.
   *
   * @see getNumArguments()
   */ public
 ASTNode getArgument(long n) {
    IntPtr cPtr = libsbmlPINVOKE.FunctionDefinition_getArgument__SWIG_0(swigCPtr, n);
    ASTNode ret = (cPtr == IntPtr.Zero) ? null : new ASTNode(cPtr, false);
    return ret;
  }

  
/**
   * Get the argument named @p name to this FunctionDefinition.
   *
   * @param name the exact name (case-sensitive) of the sought-after
   * argument
   * 
   * @return the argument (bound variable) having the given name, or @c null if
   * no such argument exists.
   */ public
 ASTNode getArgument(string name) {
    IntPtr cPtr = libsbmlPINVOKE.FunctionDefinition_getArgument__SWIG_1(swigCPtr, name);
    ASTNode ret = (cPtr == IntPtr.Zero) ? null : new ASTNode(cPtr, false);
    if (libsbmlPINVOKE.SWIGPendingException.Pending) throw libsbmlPINVOKE.SWIGPendingException.Retrieve();
    return ret;
  }

  
/**
   * Get the mathematical expression that is the body of this
   * FunctionDefinition object.
   * 
   * @return the body of this FunctionDefinition as an Abstract Syntax
   * Tree, or @c null if no body is defined.
   */ public
 ASTNode getBody() {
    IntPtr cPtr = libsbmlPINVOKE.FunctionDefinition_getBody__SWIG_0(swigCPtr);
    ASTNode ret = (cPtr == IntPtr.Zero) ? null : new ASTNode(cPtr, false);
    return ret;
  }

  
/**
   * Predicate returning @c true if the body of this
   * FunctionDefinition has set.
   *
   * @return @c true if the body of this FunctionDefinition is 
   * set, @c false otherwise.
   */ public
 bool isSetBody() {
    bool ret = libsbmlPINVOKE.FunctionDefinition_isSetBody(swigCPtr);
    return ret;
  }

  
/**
   * Get the number of arguments (bound variables) taken by this
   * FunctionDefinition.
   *
   * @return the number of arguments (bound variables) that must be passed
   * to this FunctionDefinition.
   */ public
 long getNumArguments() { return (long)libsbmlPINVOKE.FunctionDefinition_getNumArguments(swigCPtr); }

  
/**
   * Returns the libSBML type code for this %SBML object.
   * 
   *
 * 
 * LibSBML attaches an identifying code to every kind of SBML object.  These
 * are integer constants known as <em>SBML type codes</em>.  The names of all
 * the codes begin with the characters <code>SBML_</code>.
 * @if clike The set of possible type codes for core elements is defined in
 * the enumeration #SBMLTypeCode_t, and in addition, libSBML plug-ins for
 * SBML Level&nbsp;3 packages define their own extra enumerations of type
 * codes (e.g., #SBMLLayoutTypeCode_t for the Level&nbsp;3 Layout
 * package).@endif@if java In the Java language interface for libSBML, the
 * type codes are defined as static integer constants in the interface class
 * {@link libsbmlConstants}.  @endif@if python In the Python language
 * interface for libSBML, the type codes are defined as static integer
 * constants in the interface class @link libsbml@endlink.@endif@if csharp In
 * the C# language interface for libSBML, the type codes are defined as
 * static integer constants in the interface class
 * @link libsbmlcs.libsbml@endlink.@endif  Note that different Level&nbsp;3
 * package plug-ins may use overlapping type codes; to identify the package
 * to which a given object belongs, call the <code>getPackageName()</code>
 * method on the object.
 *
 *
   *
   * @return the SBML type code for this object:
   * @link libsbml#SBML_FUNCTION_DEFINITION SBML_FUNCTION_DEFINITION@endlink (default).
   *
   *
 * @warning <span class='warning'>The specific integer values of the possible
 * type codes may be reused by different Level&nbsp;3 package plug-ins.
 * Thus, to identifiy the correct code, <strong>it is necessary to invoke
 * both getTypeCode() and getPackageName()</strong>.</span>
 *
 *
   *
   * @see getElementName()
   * @see getPackageName()
   */ public new
 int getTypeCode() {
    int ret = libsbmlPINVOKE.FunctionDefinition_getTypeCode(swigCPtr);
    return ret;
  }

  
/**
   * Returns the XML element name of this object, which for
   * FunctionDefinition, is always @c 'functionDefinition'.
   * 
   * @return the name of this element, i.e., @c 'functionDefinition'.
   */ public new
 string getElementName() {
    string ret = libsbmlPINVOKE.FunctionDefinition_getElementName(swigCPtr);
    return ret;
  }

  
/**
   * Predicate returning @c true if
   * all the required attributes for this FunctionDefinition object
   * have been set.
   *
   * The required attributes for a FunctionDefinition object are:
   * @li 'id'
   *
   * @return @c true if the required attributes have been set, @c false
   * otherwise.
   */ public new
 bool hasRequiredAttributes() {
    bool ret = libsbmlPINVOKE.FunctionDefinition_hasRequiredAttributes(swigCPtr);
    return ret;
  }

  
/**
   * Predicate returning @c true if
   * all the required elements for this FunctionDefinition object
   * have been set.
   *
   * @note The required elements for a FunctionDefinition object are:
   * @li 'math'
   *
   * @return a boolean value indicating whether all the required
   * elements for this object have been defined.
   */ public new
 bool hasRequiredElements() {
    bool ret = libsbmlPINVOKE.FunctionDefinition_hasRequiredElements(swigCPtr);
    return ret;
  }

  
/**
   * Renames all the @c UnitSIdRef attributes on this element.
   *
   *
 * 
 * In SBML, unit definitions have identifiers of type <code>UnitSId</code>.  In
 * SBML Level&nbsp;3, an explicit data type called <code>UnitSIdRef</code> was
 * introduced for attribute values that refer to <code>UnitSId</code> values; in
 * previous Levels of SBML, this data type did not exist and attributes were
 * simply described to as 'referring to a unit identifier', but the effective
 * data type was the same as <code>UnitSIdRef</code> in Level&nbsp;3.  These and
 * other methods of libSBML refer to the type <code>UnitSIdRef</code> for all
 * Levels of SBML, even if the corresponding SBML specification did not
 * explicitly name the data type.
 *
 *
   *
   * This method works by looking at all unit identifier attribute values
   * (including, if appropriate, inside mathematical formulas), comparing the
   * unit identifiers to the value of @p oldid.  If any matches are found,
   * the matching identifiers are replaced with @p newid.  The method does
   * @em not descend into child elements.
   * 
   * @param oldid the old identifier
   * @param newid the new identifier
   */ public new
 void renameUnitSIdRefs(string oldid, string newid) {
    libsbmlPINVOKE.FunctionDefinition_renameUnitSIdRefs(swigCPtr, oldid, newid);
    if (libsbmlPINVOKE.SWIGPendingException.Pending) throw libsbmlPINVOKE.SWIGPendingException.Retrieve();
  }

}

}
