"""
detector - Particle detector for images
"""

import os
import sys
import cv2
import time
import logging
import numpy as np
from sysconf import CONFIG
from general_utils import make_dir
from skimage.measure import label, regionprops
from image_tools import img_fill, auto_canny, particle_canny

class Particle:

    def __init__(self, x, y, scale, maj, min, area, contrast):
        self.x = x
        self.y = y
        self.scale = scale
        self.maj = maj
        self.min = min
        self.area = area
        self.contrast = contrast

class ParticleDetector:

    def __init__(self, img=None, cfg=None, lgr=None, dbg=True):

        self.centroids = None
        self.sub_images = None
        self.input_image = img
        self.edge_image = None
        self.cfg = cfg
        self.lgr = lgr
        self.dbg = dbg
        self.particles = None

        # load the default config if non is provided
        if cfg is None:
            self.cfg = CONFIG

        print(self.cfg)

        # create a default logger if none is provided
        if self.lgr is None:
            make_dir('./', self.cfg['LOG_PATH'])
            log_file = os.path.join(self.cfg['LOG_PATH'], 'ParticleDetector-'+str(int(time.time()))+'.log')
            logging.basicConfig(filename=log_file, level=self.cfg['LOG_LEVEL'],
                                format="%(asctime)s:%(levelname)s: %(message)s")
            self.lgr = logging.getLogger().addHandler(logging.StreamHandler())

    def setup_valid(self):

        if self.input_image is None:
            self.lgr.error('Input image is not defined.')
            return False
        else:
            return True


    def detect(self):

        if not self.setup_valid():
            return

        # convert to gray if needed
        if len(self.input_image.shape) > 2:
            gray = np.mean(self.input_image, axis=2).astype('uint8')
        else:
            gray = self.input_image

        # edge detector
        edge_image = particle_canny(gray, sigma=self.cfg['PARTICLE_CANNY_SIGMA'])
        kw = self.cfg['OPEN_KERNEL_WIDTH']
        kernel = np.ones((kw, kw), np.uint8)
        edge_filled = img_fill(edge_image).astype('uint8')
        edge_filled[edge_filled > 0] = 1
        edge_image = cv2.morphologyEx(edge_filled, cv2.MORPH_OPEN, kernel)

        # localize particles and retain stats for matching
        labeled_image = label(edge_image)
        all_regions = regionprops(labeled_image, gray)

        self.particles = np.zeros((len(all_regions), 64))
        tmp_img = self.input_image.copy()
        for ind, region in enumerate(all_regions):
            self.particles[ind, 0] = region['weighted_centroid'][1]
            self.particles[ind, 1] = region['weighted_centroid'][0]
            self.particles[ind, 2] = 1.0
            self.particles[ind, 3] = region['major_axis_length']
            self.particles[ind, 4] = region['minor_axis_length']
            self.particles[ind, 5] = np.sqrt(region['area'])
            self.particles[ind, 6] = (region['max_intensity']-region['min_intensity']) / region['max_intensity']
            #cv2.drawMarker(tmp_img, (int(region['weighted_centroid'][1]), int(region['weighted_centroid'][0])), (0, 255, 0), cv2.MARKER_CROSS, 5, 1)
            # print(self.particles[ind, 0:7])

        #cv2.imshow('chan', tmp_img)
        #cv2.waitKey()

        #for chan in range(self.img.shape[-1])

if __name__=="__main__":

    img = cv2.imread(sys.argv[1])

    pd = ParticleDetector(img)
    pd.detect()


