from __future__ import division, print_function

import numpy as np
import numpy.ctypeslib as npc

from ctypes import cast, POINTER, Structure, c_int, c_float, c_double
c_float_p = POINTER(c_float)
c_double_p = POINTER(c_double)

from .vl_ctypes import LIB, c_to_np_types
from .utils import as_float_image

np_float = c_to_np_types[c_float]
np_double = c_to_np_types[c_double]


class VLDsiftKeypoint(Structure):
    _fields_ = [
        ('x', c_double),
        ('y', c_double),
        ('s', c_double),
        ('norm', c_double),
    ]


class VLDsiftDescriptorGeometry(Structure):
    _fields_ = [
        ('numBinT', c_int),
        ('numBinX', c_int),
        ('numBinY', c_int),

        ('binSizeX', c_int),
        ('binSizeY', c_int),
    ]


class VLDsiftFilter(Structure):
    _fields_ = [
        ('imWidth', c_int),
        ('imHeight', c_int),

        ('stepX', c_int),
        ('stepY', c_int),

        ('boundMinX', c_int),
        ('boundMinY', c_int),
        ('boundMaxX', c_int),
        ('boundMaxY', c_int),

        ('geom', VLDsiftDescriptorGeometry),

        ('useFlatWindow', c_int),
        ('windowSize', c_double),

        ('numFrames', c_int),
        ('descrSize', c_int),
        ('frames', POINTER(VLDsiftKeypoint)),
        ('descrs', c_float_p),

        ('numBinAlloc', c_int),
        ('numFrameAlloc', c_int),
        ('numGradAlloc', c_int),

        ('grads', POINTER(c_float_p)),
        ('convTmp1', c_float_p),
        ('convTmp2', c_float_p),