/**
 * \file    local.cpp
 * \brief   Perl-specific SWIG support code for wrapping libSBML API
 * \author  Ben Bornstein and Ben Kovitz
 * 
 * Copyright 2004 California Institute of Technology and
 * Japan Science and Technology Corporation.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  The software and
 * documentation provided hereunder is on an "as is" basis, and the
 * California Institute of Technology and Japan Science and Technology
 * Corporation have no obligations to provide maintenance, support,
 * updates, enhancements or modifications.  In no event shall the
 * California Institute of Technology or the Japan Science and Technology
 * Corporation be liable to any party for direct, indirect, special,
 * incidental or consequential damages, including lost profits, arising
 * out of the use of this software and its documentation, even if the
 * California Institute of Technology and/or Japan Science and Technology
 * Corporation have been advised of the possibility of such damage.  See
 * the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * The original code contained here was initially developed by:
 *
 *     Ben Bornstein and Ben Kovitz
 *
 *     The SBML Team
 *     Control and Dynamical Systems, MC 107-81
 *     California Institute of Technology
 *     Pasadena, CA, 91125, USA
 *
 *     http://sbml.org
 *     mailto:sbml-team@googlegroups.com
 *
 * Contributor(s):
 */

#include "sbml/SBase.h"


/**
 * @return the most specific Swig type for the given SBMLExtension object.
 */
struct swig_type_info*
GetDowncastSwigType (SBMLExtension* se)
{
	if (se == 0) return SWIGTYPE_p_SBMLExtension;
	
	const std::string pkgName = se->getName();

#include "local-downcast-extension.cpp"	

	return SWIGTYPE_p_SBMLExtension;
}


/**
 * @return the most specific Swig type for the given SBMLConverter object.
 */
struct swig_type_info*
GetDowncastSwigType (SBMLConverter* con)
{
	if (con == 0) return SWIGTYPE_p_SBMLConverter;
	
	const std::string& conName = con->getName();
	
     if (conName == "SBML Units Converter")
       return SWIGTYPE_p_SBMLUnitsConverter;
     else if (conName == "SBML Strip Package Converter")
       return SWIGTYPE_p_SBMLStripPackageConverter;
     else if (conName == "SBML Rule Converter")
       return SWIGTYPE_p_SBMLRuleConverter;
     else if (conName == "SBML Reaction Converter")
       return SWIGTYPE_p_SBMLReactionConverter;
     else if (conName == "SBML Local Parameter Converter")
       return SWIGTYPE_p_SBMLLocalParameterConverter;
     else if (conName == "SBML Level Version Converter")
       return SWIGTYPE_p_SBMLLevelVersionConverter;
     else if (conName == "SBML Initial Assignment Converter")
       return SWIGTYPE_p_SBMLInitialAssignmentConverter;
     else if (conName == "SBML Infer Units Converter")
       return SWIGTYPE_p_SBMLInferUnitsConverter;
     else if (conName == "SBML Id Converter")
       return SWIGTYPE_p_SBMLIdConverter;
     else if (conName == "SBML Function Definition Converter")
       return SWIGTYPE_p_SBMLFunctionDefinitionConverter;

#include "local-downcast-converters.cpp"	
	   
	return SWIGTYPE_p_SBMLConverter;
}

/**
 * @return the most specific Swig type for the given SBMLNamespaces object.
 */
struct swig_type_info*
GetDowncastSwigType (SBMLNamespaces* se)
{
	if (se == 0) return SWIGTYPE_p_SBMLNamespaces;
	
	const std::string pkgName = se->getPackageName();
	
#include "local-downcast-namespaces.cpp"
	
	return SWIGTYPE_p_SBMLNamespaces;
}

/**
 * @return the most specific Swig type for the given SBasePlugin object.
 */
struct swig_type_info*
GetDowncastSwigType (SBasePlugin* sbp)
{
	if (sbp == 0) return SWIGTYPE_p_SBasePlugin;
	
	const std::string pkgName = sbp->getPackageName();
	SBase* sb = sbp->getParentSBMLObject();
	if (!sb) return SWIGTYPE_p_SBasePlugin;

#include "local-downcast-plugins.cpp"

  if (sb->getTypeCode() == SBML_DOCUMENT)
    return SWIGTYPE_p_SBMLDocumentPlugin;


	return SWIGTYPE_p_SBasePlugin;
}


struct swig_type_info*
GetDowncastSwigTypeForPackage (SBase* sb, const std::string &pkgName);

/**
 * @return the most specific Swig type for the given SBase object.
 */
struct swig_type_info*
GetDowncastSwigType (SBase* sb)
{
  if (sb == 0) return SWIGTYPE_p_SBase;  
  const std::string pkgName = sb->getPackageName();
  return GetDowncastSwigTypeForPackage(sb, pkgName);
}
/**
 * @return the most specific Swig type for the given SBase object.
 */
struct swig_type_info*
GetDowncastSwigTypeForPackage (SBase* sb, const std::string &pkgName)
{
  if (sb == 0) return SWIGTYPE_p_SBase;
  
  std::string name;
	
	if (pkgName == "core")
	{
		switch (sb->getTypeCode())
		{
			case SBML_COMPARTMENT:
				return SWIGTYPE_p_Compartment;
				
			case SBML_COMPARTMENT_TYPE:
				return SWIGTYPE_p_CompartmentType;
				
			case SBML_CONSTRAINT:
				return SWIGTYPE_p_Constraint;
				
			case SBML_DOCUMENT:
				return SWIGTYPE_p_SBMLDocument;
				
			case SBML_EVENT:
				return SWIGTYPE_p_Event;
				
			case SBML_EVENT_ASSIGNMENT:
				return SWIGTYPE_p_EventAssignment;
				
			case SBML_FUNCTION_DEFINITION:
				return SWIGTYPE_p_FunctionDefinition;
				
			case SBML_INITIAL_ASSIGNMENT:
				return SWIGTYPE_p_InitialAssignment;
				
			case SBML_KINETIC_LAW:
				return SWIGTYPE_p_KineticLaw;
				
			case SBML_LIST_OF:
				name = sb->getElementName();
				if(name == "listOf"){
					return SWIGTYPE_p_ListOf;
				}
				else if(name == "listOfCompartments"){
					return SWIGTYPE_p_ListOfCompartments;
				}
				else if(name == "listOfCompartmentTypes"){
					return SWIGTYPE_p_ListOfCompartmentTypes;
				}
				else if(name == "listOfConstraints"){
					return SWIGTYPE_p_ListOfConstraints;
				}
				else if(name == "listOfEvents"){
					return SWIGTYPE_p_ListOfEvents;
				}
				else if(name == "listOfEventAssignments"){
					return SWIGTYPE_p_ListOfEventAssignments;
				}
				else if(name == "listOfFunctionDefinitions"){
					return SWIGTYPE_p_ListOfFunctionDefinitions;
				}
				else if(name == "listOfInitialAssignments"){
					return SWIGTYPE_p_ListOfInitialAssignments;
				}
				else if(name == "listOfParameters"){
					return SWIGTYPE_p_ListOfParameters;
				}
				else if(name == "listOfLocalParameters"){
					return SWIGTYPE_p_ListOfLocalParameters;
				}
				else if(name == "listOfReactions"){
					return SWIGTYPE_p_ListOfReactions;
				}
				else if(name == "listOfRules"){
					return SWIGTYPE_p_ListOfRules;
				}
				else if(name == "listOfSpecies"){
					return SWIGTYPE_p_ListOfSpecies;
				}
				else if(name == "listOfUnknowns"){
					return SWIGTYPE_p_ListOfSpeciesReferences;
				}
				else if(name == "listOfReactants"){
					return SWIGTYPE_p_ListOfSpeciesReferences;
				}
				else if(name == "listOfProducts"){
					return SWIGTYPE_p_ListOfSpeciesReferences;
				}
				else if(name == "listOfModifiers"){
					return SWIGTYPE_p_ListOfSpeciesReferences;
				}
				else if(name == "listOfSpeciesTypes"){
					return SWIGTYPE_p_ListOfSpeciesTypes;
				}
				else if(name == "listOfUnits"){
					return SWIGTYPE_p_ListOfUnits;
				}
				else if(name == "listOfUnitDefinitions"){
					return SWIGTYPE_p_ListOfUnitDefinitions;
				}
				return SWIGTYPE_p_ListOf;
				
			case SBML_MODEL:
				return SWIGTYPE_p_Model;
				
			case SBML_PARAMETER:
				return SWIGTYPE_p_Parameter;
				
			case SBML_LOCAL_PARAMETER:
				return SWIGTYPE_p_LocalParameter;
				
			case SBML_REACTION:
				return SWIGTYPE_p_Reaction;
				
			case SBML_SPECIES:
				return SWIGTYPE_p_Species;
				
			case SBML_SPECIES_REFERENCE:
				return SWIGTYPE_p_SpeciesReference;
				
			case SBML_MODIFIER_SPECIES_REFERENCE:
				return SWIGTYPE_p_ModifierSpeciesReference;
				
			case SBML_SPECIES_TYPE:
				return SWIGTYPE_p_SpeciesType;
				
			case SBML_UNIT_DEFINITION:
				return SWIGTYPE_p_UnitDefinition;
				
			case SBML_UNIT:
				return SWIGTYPE_p_Unit;
				
			case SBML_ALGEBRAIC_RULE:
				return SWIGTYPE_p_AlgebraicRule;
				
			case SBML_ASSIGNMENT_RULE:
				return SWIGTYPE_p_AssignmentRule;
				
			case SBML_RATE_RULE:
				return SWIGTYPE_p_RateRule;
				
			case SBML_DELAY:
				return SWIGTYPE_p_Delay;
				
			case SBML_TRIGGER:
				return SWIGTYPE_p_Trigger;
				
			case SBML_STOICHIOMETRY_MATH:
				return SWIGTYPE_p_StoichiometryMath;
				
    case SBML_PRIORITY:
      return SWIGTYPE_p_Priority;

			default:
				return SWIGTYPE_p_SBase;
		}
	}

#include "local-downcast.cpp"

  return SWIGTYPE_p_SBase;
}


/**
 * @return the most specific Swig type for the given ASTBasePlugin object.
 */
struct swig_type_info*
GetDowncastSwigType (ASTBasePlugin* sbp)
{
  if (sbp == 0) return SWIGTYPE_p_ASTBasePlugin;

  const std::string pkgName = sbp->getPackageName();
	
#include "local-downcast-astplugins.cpp"

  return SWIGTYPE_p_ASTBasePlugin;
}


