
MIN_HIGH_SURROGATE = 55296
MAX_HIGH_SURROGATE = 0xDBFF
MIN_LOW_SURROGATE  = 56320
MIN_SUPPLEMENTARY_CODE_POINT = 0x010000
MIN_CODE_POINT = 0x000000;
MAX_CODE_POINT = 0X10FFFF;


def isBmpCodePoint(ch):
    """
    :type ch: int
    :rtype bool
    """
    # unsigned right shift
    return ch >> 16 == 0

def isValidCodePoint(ch):
    """
    :type ch: int
    :rtype: bool
    """
    return ch >= MIN_CODE_POINT and ch <= MAX_CODE_POINT

def isHighSurrogate(ch):
    """
    :type ch: int
    :rtype: bool
    """
    return ch >= MIN_HIGH_SURROGATE and ch <= MAX_HIGH_SURROGATE

def lowSurrogate(ch):
    """
    :type ch: int
    :rtype: int
    """
    return ((ch & 0x3ff) + MIN_LOW_SURROGATE);

def highSurrogate(ch):
    """
    :type ch: int
    :rtype: int
    """
    # unsigned right shift
    return ((ch >> 10) + (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >> 10)));

def charCount(ch):
    """
    :type ch: int
    :rtype: int
    """
    return 2 if ch >= MIN_SUPPLEMENTARY_CODE_POINT else 1;

def toCodePoint(high, low):
    """
    :type high: int
    :type low: int
    :rtype: bool
    """
    return ((high << 10) + low) + (MIN_SUPPLEMENTARY_CODE_POINT - (MIN_HIGH_SURROGATE << 10) - MIN_LOW_SURROGATE);
