import e32
import _fastcamera
import graphics
from _fastcamera import ERangeMacro, ERangeNormal, ERangePortrait, ERangeInfinite
number_of_devices = _fastcamera.cameras_available()
_my_viewfinder_call_back = None
_my_photo_call_back = None
_backlight_on = 0
modemap = {'RGB': _fastcamera.EColor16M,
 'RGB16': _fastcamera.EColor64K,
 'RGB12': _fastcamera.EColor4K,
 'JPEG_Exif': _fastcamera.EFormatExif,
 'JPEG_JFIF': _fastcamera.EFormatJpeg}
flashmap = {'none': _fastcamera.EFlashNone,
 'auto': _fastcamera.EFlashAuto,
 'forced': _fastcamera.EFlashForced,
 'fill_in': _fastcamera.EFlashFillIn,
 'red_eye_reduce': _fastcamera.EFlashRedEyeReduce}
whitebalancemap = {'auto': _fastcamera.EWBAuto,
 'daylight': _fastcamera.EWBDaylight,
 'cloudy': _fastcamera.EWBCloudy,
 'tungsten': _fastcamera.EWBTungsten,
 'fluorescent': _fastcamera.EWBFluorescent,
 'flash': _fastcamera.EWBFlash}
exposuremap = {'auto': _fastcamera.EExposureAuto,
 'night': _fastcamera.EExposureNight,
 'backlight': _fastcamera.EExposureBacklight,
 'center': _fastcamera.EExposureCenter}

def Camera(camIndex):
    ret = _fastcamera.Camera(camIndex)
    return ret

def InfoCamera(camIndex):
    return _fastcamera.InfoCamera(camIndex)

def cameras_available():
    return _fastcamera.cameras_available()

def _finder_call_back(err, image_frame):
    if _backlight_on:
        e32.reset_inactivity()
    bmp = None
    if (err == 0):
        bmp = graphics.Image.from_cfbsbitmap(image_frame)
    _my_viewfinder_call_back(err, bmp)

def _bitmap_photo_call_back(err, image_frame):
    bmp = None
    if (err == 0):
        bmp = graphics.Image.from_cfbsbitmap(image_frame)
    _my_photo_call_back(err, bmp)

def _main_pane_size():
    try:
        if (e32.s60_version_info >= (2, 8)):
            import appuifw
            return appuifw.app.layout(appuifw.EMainPane)[0]
    except:
        pass
    return (176, 144)

def prepare_take_photo(cameraToUse, mode = 'RGB16', size = (640, 480)):
    s = -1
    for i in range(cameraToUse.max_image_size()):
        if (cameraToUse.image_size(modemap[mode], i) == size):
            s = i
            break

    if (s == -1):
        raise ValueError, 'Size not supported for camera'
    cameraToUse.prepare_take_photo(modemap[mode], s)

def take_photo(cameraToUse, callback):
    global _my_photo_call_back
    if cameraToUse.taking_photo():
        raise RuntimeError, 'Already taking photo'
    _my_photo_call_back = callback
    mode = cameraToUse.mode()
    if ((mode == _fastcamera.EFormatExif) or (mode == _fastcamera.EFormatJpeg)):
        cameraToUse.take_photo(_my_photo_call_back)
    else:
        cameraToUse.take_photo(_bitmap_photo_call_back)

def start_finder(cameraToUse, call_back, backlight_on = 1, size = _main_pane_size()):
    global _my_viewfinder_call_back
    global _backlight_on
    if cameraToUse.finder_on():
        raise RuntimeError, 'View finder is started already'
    if (not callable(call_back)):
        raise TypeError(("'%s' is not callable" % call_back))
    _my_viewfinder_call_back = call_back
    _backlight_on = backlight_on
    cameraToUse.start_finder(_finder_call_back, size)

def stop_finder(cameraToUse):
    cameraToUse.stop_finder()
    _my_viewfinder_call_back = None

def image_modes(cameraToUse):
    ret = []
    modes = cameraToUse.image_modes()
    for key in modemap:
        if (modes & modemap[key]):
            ret.append(key)

    return ret

def image_sizes(cameraToUse, mode = 'RGB16'):
    sizes = []
    for i in range(cameraToUse.max_image_size()):
        s = cameraToUse.image_size(modemap[mode], i)
        if (s != (0, 0)):
            sizes.append(s)

    return sizes

def flash_modes(cameraToUse):
    ret = []
    modes = cameraToUse.flash_modes()
    for key in flashmap:
        if (modes & flashmap[key]):
            ret.append(key)
        if (flashmap[key] == 0):
            ret.append(key)

    return ret

def exposure_modes(cameraToUse):
    ret = []
    modes = cameraToUse.exposure_modes()
    for key in exposuremap:
        if (modes & exposuremap[key]):
            ret.append(key)
        if (exposuremap[key] == 0):
            ret.append(key)

    return ret

def white_balance_modes(cameraToUse):
    ret = []
    modes = cameraToUse.white_balance_modes()
    for key in whitebalancemap:
        if (modes & whitebalancemap[key]):
            ret.append(key)
        if (whitebalancemap[key] == 0):
            ret.append(key)

    return ret

def release():
    return