# This file was automatically generated by SWIG (https://www.swig.org).
# Version 4.1.0
#
# Do not make changes to this file unless you know what you are doing - modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _pythonnator
else:
    import _pythonnator

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "this":
            set(self, name, value)
        elif name == "thisown":
            self.this.own(value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


class Type(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getName(self):
        return _pythonnator.Type_getName(self)

    def isValid(self):
        return _pythonnator.Type_isValid(self)

    def getFeatureByBaseName(self, feature):
        return _pythonnator.Type_getFeatureByBaseName(self, feature)

    def getAppropriateFeatures(self):
        return _pythonnator.Type_getAppropriateFeatures(self)

    def __init__(self):
        _pythonnator.Type_swiginit(self, _pythonnator.new_Type())
    __swig_destroy__ = _pythonnator.delete_Type

# Register Type in _pythonnator:
_pythonnator.Type_swigregister(Type)
class Feature(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def isValid(self):
        return _pythonnator.Feature_isValid(self)

    def getName(self):
        return _pythonnator.Feature_getName(self)

    def getRangeType(self):
        return _pythonnator.Feature_getRangeType(self)

    def getIntroType(self):
        return _pythonnator.Feature_getIntroType(self)

    def __init__(self):
        _pythonnator.Feature_swiginit(self, _pythonnator.new_Feature())
    __swig_destroy__ = _pythonnator.delete_Feature

# Register Feature in _pythonnator:
_pythonnator.Feature_swigregister(Feature)
class TypeSystem(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    def getType(self, crName):
        return _pythonnator.TypeSystem_getType(self, crName)

# Register TypeSystem in _pythonnator:
_pythonnator.TypeSystem_swigregister(TypeSystem)
class CAS(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    def iterator(self):
        return _pythonnator.CAS_iterator(self)

    def getIndexRepository(self):
        return _pythonnator.CAS_getIndexRepository(self)

    def createFS(self, arg2):
        return _pythonnator.CAS_createFS(self, arg2)

    def getTypeSystem(self):
        return _pythonnator.CAS_getTypeSystem(self)

    def getAnnotationIndex(self, type):
        return _pythonnator.CAS_getAnnotationIndex(self, type)

    def setDocumentText(self, text):
        return _pythonnator.CAS_setDocumentText(self, text)

    def getDocumentText(self):
        return _pythonnator.CAS_getDocumentText(self)

    def setSofaDataString(self, text, mimetype):
        return _pythonnator.CAS_setSofaDataString(self, text, mimetype)

    def setSofaDataArray(self, array, mime):
        return _pythonnator.CAS_setSofaDataArray(self, array, mime)

    def setSofaDataURI(self, uri, mime):
        return _pythonnator.CAS_setSofaDataURI(self, uri, mime)

    def getSofaDataURI(self):
        return _pythonnator.CAS_getSofaDataURI(self)

    def createAnnotation(self, type, uiBeginPos, uiEndPos):
        return _pythonnator.CAS_createAnnotation(self, type, uiBeginPos, uiEndPos)

    def getView(self, viewName):
        return _pythonnator.CAS_getView(self, viewName)

    def createView(self, sofaName):
        return _pythonnator.CAS_createView(self, sofaName)

    def getSofa(self, *args):
        return _pythonnator.CAS_getSofa(self, *args)

# Register CAS in _pythonnator:
_pythonnator.CAS_swigregister(CAS)
class FeatureStructure(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getCAS(self):
        return _pythonnator.FeatureStructure_getCAS(self)

    def isValid(self):
        return _pythonnator.FeatureStructure_isValid(self)

    def getType(self):
        return _pythonnator.FeatureStructure_getType(self)

    def clone(self, *args):
        return _pythonnator.FeatureStructure_clone(self, *args)

    def isUntouchedFSValue(self, crFeature):
        return _pythonnator.FeatureStructure_isUntouchedFSValue(self, crFeature)

    def getFSValue(self, crFeature):
        return _pythonnator.FeatureStructure_getFSValue(self, crFeature)

    def setFSValue(self, crFeature, anFS):
        return _pythonnator.FeatureStructure_setFSValue(self, crFeature, anFS)

    def getIntValue(self, crFeature):
        return _pythonnator.FeatureStructure_getIntValue(self, crFeature)

    def setIntValue(self, crFeature, i):
        return _pythonnator.FeatureStructure_setIntValue(self, crFeature, i)

    def getFloatValue(self, crFeature):
        return _pythonnator.FeatureStructure_getFloatValue(self, crFeature)

    def setFloatValue(self, crFeature, arg3):
        return _pythonnator.FeatureStructure_setFloatValue(self, crFeature, arg3)

    def getStringValue(self, crFeature):
        return _pythonnator.FeatureStructure_getStringValue(self, crFeature)

    def setStringValue(self, crFeature, cuStr):
        return _pythonnator.FeatureStructure_setStringValue(self, crFeature, cuStr)

    def __init__(self):
        _pythonnator.FeatureStructure_swiginit(self, _pythonnator.new_FeatureStructure())
    __swig_destroy__ = _pythonnator.delete_FeatureStructure

# Register FeatureStructure in _pythonnator:
_pythonnator.FeatureStructure_swigregister(FeatureStructure)
class AnnotationFS(FeatureStructure):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getBeginPosition(self):
        return _pythonnator.AnnotationFS_getBeginPosition(self)

    def getEndPosition(self):
        return _pythonnator.AnnotationFS_getEndPosition(self)

    def getLength(self):
        return _pythonnator.AnnotationFS_getLength(self)

    def getCoveredText(self):
        return _pythonnator.AnnotationFS_getCoveredText(self)

    def __init__(self):
        _pythonnator.AnnotationFS_swiginit(self, _pythonnator.new_AnnotationFS())
    __swig_destroy__ = _pythonnator.delete_AnnotationFS

# Register AnnotationFS in _pythonnator:
_pythonnator.AnnotationFS_swigregister(AnnotationFS)
class SofaFS(FeatureStructure):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def getSofaURI(self):
        return _pythonnator.SofaFS_getSofaURI(self)

    def getSofaMime(self):
        return _pythonnator.SofaFS_getSofaMime(self)

    def __init__(self):
        _pythonnator.SofaFS_swiginit(self, _pythonnator.new_SofaFS())
    __swig_destroy__ = _pythonnator.delete_SofaFS

# Register SofaFS in _pythonnator:
_pythonnator.SofaFS_swigregister(SofaFS)
class FSIndexRepository(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    def getIndex(self, crLabel):
        return _pythonnator.FSIndexRepository_getIndex(self, crLabel)

    def getIndexByType(self, crLabel, type):
        return _pythonnator.FSIndexRepository_getIndexByType(self, crLabel, type)

    def addFS(self, fs):
        return _pythonnator.FSIndexRepository_addFS(self, fs)

# Register FSIndexRepository in _pythonnator:
_pythonnator.FSIndexRepository_swigregister(FSIndexRepository)
class FSIterator(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def isValid(self):
        return _pythonnator.FSIterator_isValid(self)

    def get(self):
        return _pythonnator.FSIterator_get(self)

    def moveToNext(self):
        return _pythonnator.FSIterator_moveToNext(self)

    def moveToPrevious(self):
        return _pythonnator.FSIterator_moveToPrevious(self)

    def moveToFirst(self):
        return _pythonnator.FSIterator_moveToFirst(self)

    def moveToLast(self):
        return _pythonnator.FSIterator_moveToLast(self)

    def moveTo(self, fs):
        return _pythonnator.FSIterator_moveTo(self, fs)

    def peekNext(self):
        return _pythonnator.FSIterator_peekNext(self)

    def peekPrevious(self):
        return _pythonnator.FSIterator_peekPrevious(self)

    def __init__(self):
        _pythonnator.FSIterator_swiginit(self, _pythonnator.new_FSIterator())
    __swig_destroy__ = _pythonnator.delete_FSIterator

# Register FSIterator in _pythonnator:
_pythonnator.FSIterator_swigregister(FSIterator)
class ANIterator(FSIterator):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    def get(self):
        return _pythonnator.ANIterator_get(self)

# Register ANIterator in _pythonnator:
_pythonnator.ANIterator_swigregister(ANIterator)
class ResultSpecification(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

# Register ResultSpecification in _pythonnator:
_pythonnator.ResultSpecification_swigregister(ResultSpecification)
class AnnotatorContext(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    def extractValue(self, paramName):
        return _pythonnator.AnnotatorContext_extractValue(self, paramName)

    def extractStringValue(self, paramName):
        return _pythonnator.AnnotatorContext_extractStringValue(self, paramName)

    def extractIntegerValue(self, paramName):
        return _pythonnator.AnnotatorContext_extractIntegerValue(self, paramName)

    def extractFloatValue(self, paramName):
        return _pythonnator.AnnotatorContext_extractFloatValue(self, paramName)

    def logMessage(self, message):
        return _pythonnator.AnnotatorContext_logMessage(self, message)

    def logWarning(self, message):
        return _pythonnator.AnnotatorContext_logWarning(self, message)

    def logError(self, message):
        return _pythonnator.AnnotatorContext_logError(self, message)

# Register AnnotatorContext in _pythonnator:
_pythonnator.AnnotatorContext_swigregister(AnnotatorContext)
class FSIndex(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def isValid(self):
        return _pythonnator.FSIndex_isValid(self)

    def getSize(self):
        return _pythonnator.FSIndex_getSize(self)

    def find(self, anFS):
        return _pythonnator.FSIndex_find(self, anFS)

    def iterator(self):
        return _pythonnator.FSIndex_iterator(self)

    def __init__(self):
        _pythonnator.FSIndex_swiginit(self, _pythonnator.new_FSIndex())
    __swig_destroy__ = _pythonnator.delete_FSIndex

# Register FSIndex in _pythonnator:
_pythonnator.FSIndex_swigregister(FSIndex)
class ANIndex(FSIndex):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _pythonnator.ANIndex_iterator(self)

    def __init__(self):
        _pythonnator.ANIndex_swiginit(self, _pythonnator.new_ANIndex())
    __swig_destroy__ = _pythonnator.delete_ANIndex

# Register ANIndex in _pythonnator:
_pythonnator.ANIndex_swigregister(ANIndex)

