

#The constants for locking 
READ_LOCK=1
WRITE_LOCK=2
UPGRADE_LOCK=3


#System level repo IDS
g_systemLevelRepoIds = {'DBOBJECT':1,
                        'OBJECT':2,
                        'LITERAL':3,
                        'SCOPE':4,
                        'REPOSITORY_OBJECT':5,
                        'META_OBJECT':6,
                        'DEFINING_SCOPE':7,
                        'MODULE':8,

                        'STRING_LIST':40,
                        }


g_systemLevelTables = {2:'ftods_object',
                             3:'ftods_literal'
                             }


class Types:
    BOOLEAN = 1
    SIGNED_SHORT = 2
    STRING = 3
    UNSIGNED_SHORT = 4
    SIGNED_LONG = 5
    UNSIGNED_LONG = 6
    SIGNED_LONG_LONG = 7
    FLOAT = 8
    DOUBLE = 9
    CHAR = 10
    DATE = 11
    TIME = 12
    TIMESTAMP = 13
    INTERVAL = 14
    OCTET = 15
    VOID = 16


    POBJECT=20
    ENUMERATION = 21
    STRUCTURE = 22
    UNION = 23
    ROBJECT = 24

    LIST_COLLECTION = 30
    SET_COLLECTION = 31
    BAG_COLLECTION = 32
    ARRAY_COLLECTION = 33
    DICTIONARY_COLLECTION = 34
    FIXEDSTRING = 35


    BLOB=100
    EXCEPTION=101




g_listTypes = {}
g_allTypes = []

g_primitiveTypes = {}
g_literalTypes = {}

for name,value in Types.__dict__.items():
    if name[0] == '_': continue
    g_listTypes[value] = 0
    g_primitiveTypes[value] = 0
    g_literalTypes[value] = 0
    g_allTypes.append(value)

g_listTypes[Types.LIST_COLLECTION] = 1
g_listTypes[Types.SET_COLLECTION] = 1
g_listTypes[Types.BAG_COLLECTION] = 1
g_listTypes[Types.ARRAY_COLLECTION] = 1
g_listTypes[Types.DICTIONARY_COLLECTION] = 1


g_primitiveTypes[Types.STRING] = 1
g_primitiveTypes[Types.UNSIGNED_SHORT] = 1
g_primitiveTypes[Types.BOOLEAN] = 1
g_primitiveTypes[Types.UNSIGNED_LONG] = 1
g_primitiveTypes[Types.SIGNED_SHORT] = 1
g_primitiveTypes[Types.DOUBLE] = 1
g_primitiveTypes[Types.SIGNED_LONG_LONG] = 1
g_primitiveTypes[Types.SIGNED_LONG] = 1
g_primitiveTypes[Types.FLOAT] = 1
g_primitiveTypes[Types.CHAR] = 1
g_primitiveTypes[Types.OCTET] = 1


g_literalTypes[Types.DATE] = 1
g_literalTypes[Types.TIME] = 1
g_literalTypes[Types.TIMESTAMP] = 1
g_literalTypes[Types.INTERVAL] = 1
g_literalTypes[Types.STRUCTURE] = 1
g_literalTypes[Types.ENUMERATION] = 1
g_literalTypes[Types.UNION] = 1
g_literalTypes[Types.FIXEDSTRING] = 1




import types
try:
    g_stringTypes= [types.StringType, types.UnicodeType]
except:
    g_stringTypes= [types.StringType]


def StringTypeCheck(val,repoType):
    if type(val) not in g_stringTypes:
        raise TypeError("expected string type, got %s" % type(val))

def IntTypeCheck(val,repoType):
    if type(val) != types.IntType:
        raise TypeError("expected int type, got %s" % type(val))

def BooleanTypeCheck(val,repoType):
    IntTypeCheck(val,repoType)
    if val not in [0,1]:
        raise TypeError("expected 0 or 1 , got %d" % val)
       

def LongTypeCheck(val,repoType):
    if type(val) not in [types.IntType,types.LongType]:
        raise TypeError("expected int or long type, got %s" % type(val))

def DoubleTypeCheck(val,repoType):
    if type(val) not in [types.FloatType,types.IntType,types.LongType]:
        raise TypeError("expected float, int or long type, got %s" % type(val))

def CharTypeCheck(val,repoType):
    StringTypeCheck(val,repoType)
    if len(val) != 1:
        raise TypeError("expected string of length one, got %s" % val)

def OctetTypeCheck(val,repoType):
    IntTypeCheck(val,repoType)
    if val < 0 or val > 255:
        raise TypeError("expected octet (8 bit value), got %d" % val)

def DateTypeCheck(val,repoType):
    from Ft.Ods import Date
    if not isinstance(val,Date.Date):
        raise TypeError("expected instance of Ft.Ods.Date, %s found" % str(val))

def TimeTypeCheck(val,repoType):
    from Ft.Ods import TimeImp
    if not isinstance(val,TimeImp.TimeImp):
        raise TypeError("expected instance of Ft.Ods.TimeImp, %s found" % str(val))

def IntervalTypeCheck(val,repoType):
    from Ft.Ods import Interval
    if not isinstance(val,Interval.Interval):
        raise TypeError("expected instance of Ft.Ods.Interval, %s found" % str(val))


def TimestampTypeCheck(val,repoType):
    from Ft.Ods import TimeStamp
    if not isinstance(val,TimeStamp.TimeStamp):
        raise TypeError("expected instance of Ft.Ods.TimeStamp, %s found" % str(val))

def VoidTypeCheck(val,repoType):
    if val != None:
        raise TypeError("expected None, %s found" % str(val))
        

def PObjectTypeCheck(val,repoType):
    from Ft.Ods import Object
    if not isinstance(val,Object.Object):
        raise TypeError("expected instance of Ft.Ods.Object, %s found" % str(val))
    if repoType not in val._typeIds:
        raise TypeError("expected instance of type %s, %s found" % (repoType,str(val._typeIds)))
        

def RObjectTypeCheck(val,repoType):
    from Ft.Ods.MetaData import RepositoryObject
    if not isinstance(val,RepositoryObject.RepositoryObject):
        raise TypeError("expected instance of Ft.Ods.MetaData.RepositoryObject, %s found" % str(val))

def EnumerationTypeCheck(val,repoType):
    from Ft.Ods import Enumeration
    if not isinstance(val,Enumeration.EnumElement):
        raise TypeError("expected instance of Ft.Ods.EnumElement, %s found" % str(val))
    if repoType not in val._typeIds:
        raise TypeError("expected instance of type %s, %s found" % (repoType,str(val._typeIds)))

def StructureTypeCheck(val,repoType):
    from Ft.Ods import Structure
    if not isinstance(val,Structure.Structure):
        raise TypeError("expected instance of Ft.Ods.Structure, %s found" % str(val))
    if repoType not in val._typeIds:
        raise TypeError("expected instance of type %s, %s found" % (repoType,str(val._typeIds)))

def UnionTypeCheck(val,repoType):
    from Ft.Ods import Union
    if not isinstance(val,Union.Union):
        raise TypeError("expected instance of Ft.Ods.Union, %s found" % str(val))
    if repoType not in val._typeIds:
        raise TypeError("expected instance of type %s, %s found" % (repoType,str(val._typeIds)))

def FixedStringTypeCheck(val,repoType):
    from Ft.Ods import FixedString
    if not isinstance(val,FixedString.FixedString):
        raise TypeError("expected instance of Ft.Ods.FixedString, %s found" % str(val))



def ListTypeCheck(val,repoType):
    from Ft.Ods.Collections import CollectionBase,ListBase
    if not isinstance(val,CollectionBase.CollectionBase):
        raise TypeError("expected instance of Ft.Ods.Collections.CollectionBase.CollectionBase, %s found" % str(val))
    if not isinstance(val,ListBase.ListBase):
        raise TypeError("expected instance of Ft.Ods.Collections.ListBase.ListBase, %s found" % str(val))

    if repoType not in val._typeIds:
        raise TypeError("expected instance of type %s, %s found" % (repoType,str(val._typeIds)))

def SetTypeCheck(val,repoType):
    from Ft.Ods.Collections import CollectionBase,SetBase
    if not isinstance(val,CollectionBase.CollectionBase):
        raise TypeError("expected instance of Ft.Ods.Collections.CollectionBase.CollectionBase, %s found" % str(val))
    if not isinstance(val,SetBase.SetBase):
        raise TypeError("expected instance of Ft.Ods.Collections.SetBase.SetBase, %s found" % str(val))

    if repoType not in val._typeIds:
        raise TypeError("expected instance of type %s, %s found" % (repoType,str(val._typeIds)))

def BagTypeCheck(val,repoType):
    from Ft.Ods.Collections import CollectionBase,BagBase
    if not isinstance(val,CollectionBase.CollectionBase):
        raise TypeError("expected instance of Ft.Ods.Collections.CollectionBase.CollectionBase, %s found" % str(val))
    if not isinstance(val,BagBase.BagBase):
        raise TypeError("expected instance of Ft.Ods.Collections.BagBase.BagBase, %s found" % str(val))

    if repoType not in val._typeIds:
        raise TypeError("expected instance of type %s, %s found" % (repoType,str(val._typeIds)))

def DictionaryTypeCheck(val,repoType):
    from Ft.Ods.Collections import DictionaryBase
    if not isinstance(val,DictionaryBase.DictionaryBase):
        raise TypeError("expected instance of Ft.Ods.Collections.DictionaryBase.DictionaryBase, %s found" % str(val))
    if repoType not in val._typeIds:
        raise TypeError("expected instance of type %s, %s found" % (repoType,str(val._typeIds)))



def ArrayTypeCheck(val,repoType):
    from Ft.Ods.Exception import FtodsUnsupportedError
    raise FtodsUnsupportedError("Arrays are not supported")


g_typeCheck = {
    Types.STRING:StringTypeCheck,
    Types.UNSIGNED_SHORT:IntTypeCheck,
    Types.BOOLEAN:BooleanTypeCheck,
    Types.UNSIGNED_LONG:LongTypeCheck,
    Types.SIGNED_SHORT:IntTypeCheck,
    Types.DOUBLE:DoubleTypeCheck,
    Types.SIGNED_LONG_LONG:LongTypeCheck,
    Types.SIGNED_LONG:LongTypeCheck,
    Types.FLOAT:DoubleTypeCheck,
    Types.BLOB:StringTypeCheck,
    Types.CHAR:CharTypeCheck,
    Types.OCTET:OctetTypeCheck,
    Types.DATE:DateTypeCheck,
    Types.TIME:TimeTypeCheck,
    Types.INTERVAL:IntervalTypeCheck,
    Types.TIMESTAMP:TimestampTypeCheck,
    Types.VOID:VoidTypeCheck,
    Types.POBJECT:PObjectTypeCheck,
    Types.ROBJECT:RObjectTypeCheck,
    Types.ENUMERATION:EnumerationTypeCheck,
    Types.STRUCTURE:StructureTypeCheck,
    Types.UNION:UnionTypeCheck,

    Types.LIST_COLLECTION:ListTypeCheck,
    Types.SET_COLLECTION:SetTypeCheck,
    Types.BAG_COLLECTION:BagTypeCheck,
    Types.ARRAY_COLLECTION:ArrayTypeCheck,
    Types.DICTIONARY_COLLECTION:DictionaryTypeCheck,
    Types.FIXEDSTRING:FixedStringTypeCheck,

    }

g_odmgTypeToString = {Types.BOOLEAN : 'boolean',
                      Types.SIGNED_SHORT : 'short',
                      Types.STRING : 'string',
                      Types.UNSIGNED_SHORT : 'unsigned short',
                      Types.SIGNED_LONG : 'signed long',
                      Types.UNSIGNED_LONG : 'unsigned long',
                      Types.SIGNED_LONG_LONG : 'signed long long',
                      Types.FLOAT : 'float',
                      Types.DOUBLE : 'double',
                      Types.CHAR:'char',
                      Types.OCTET:'octet',
                      Types.DATE:'date',
                      Types.TIME:'time',
                      Types.INTERVAL:'interval',
                      Types.TIMESTAMP:'timestamp',
                      Types.VOID:'void',
                      Types.POBJECT:'pstub object',
                      Types.ROBJECT:'repository object',
                      Types.ENUMERATION:'enumeration',
                      Types.STRUCTURE:'struct',
                      Types.UNION:'union',

                      Types.LIST_COLLECTION:'list',
                      Types.SET_COLLECTION:'set',
                      Types.BAG_COLLECTION:'bag',
                      Types.ARRAY_COLLECTION:'array',
                      Types.DICTIONARY_COLLECTION:'dictionary',
                      Types.FIXEDSTRING:'string <n>',

                      Types.BLOB: 'blob',

                      }


class CollectionChanges:
    INSERT = 1
    REMOVE = 2
    APPEND = 3
    REMOVE_END = 4

class DictionaryChanges:
    ADD = 1
    REMOVE = 2
    CHANGE = 3



class CollectionTypes:
    LIST = 1
    BAG = 2
    SET = 3

