from gamera.core import *
from gamera.core import Point,FloatPoint, ONEBIT, RGBPixel
from OMRnotes.scripts.classification.dist import Distance
from OMRnotes.scripts.classification.head import *
from OMRnotes.scripts.classification.halfhead import Halfheads
from OMRnotes.scripts.classification.seg import Seg
from OMRnotes.scripts.classification.searcher import Searcher2
from scipy import signal
import numpy as np
from scipy import *

class Segmenter():
    '''Segmentacni trida
    '''
    def __init__(self):
        pass

    def deletebeams(self, beams, img):
        '''Odstraneni tramcu
        '''
        temp = img.image_copy()
        for beam in beams:
            temp.highlight(beam.seg, 0)
        return temp.image_copy()

    def deletesegments(self, seg, img):
        '''Odstraneni segmentu
        '''
        temp = img.image_copy()
        for c in seg:
            temp.draw_filled_rect(FloatPoint(c.ul_x, c.ul_y),
                                  FloatPoint(c.lr_x, c.lr_y), 0)
        return temp.image_copy()

    def deletehalfnotes(self, halfheads, img):
        '''Odstraneni pulovych not
        '''
        temp = img.image_copy()
        for head in halfheads:
            if head.dot:
                temp.draw_filled_rect(FloatPoint(head.dot.ul_x, head.dot.ul_y),
                                  FloatPoint(head.dot.lr_x, head.dot.lr_y), 0)

            temp.draw_filled_rect(FloatPoint(head.seghead.ul_x - 8, head.seghead.ul_y - 8),
                                  FloatPoint(head.seghead.lr_x + 8, head.seghead.lr_y + 8), 0)

            temp.draw_filled_rect(FloatPoint(head.segline.ul_x, head.segline.ul_y),
                                  FloatPoint(head.segline.lr_x, head.segline.lr_y), 0)

        return temp.image_copy()

    def deletefullnotes(self, heads, beams, img):
        '''Odstraneni not s plnou hlavickou vcetne praporku a tecky
        '''
        temp = img.image_copy()
        for head in heads:
            if head.dot:
                temp.draw_filled_rect(FloatPoint(head.dot.ul_x, head.dot.ul_y),
                                  FloatPoint(head.dot.lr_x, head.dot.lr_y), 0)

            if head.flag:
                temp.draw_filled_rect(FloatPoint(head.flag.ul_x, head.flag.ul_y),
                                      FloatPoint(head.flag.lr_x, head.flag.lr_y), 0)

            temp.draw_filled_rect(FloatPoint(head.seghead.ul_x - 8, head.seghead.ul_y - 8),
                                  FloatPoint(head.seghead.lr_x + 8, head.seghead.lr_y + 8), 0)

            temp.draw_filled_rect(FloatPoint(head.segline.ul_x, head.segline.ul_y),
                                  FloatPoint(head.segline.lr_x, head.segline.lr_y), 0)

        temp = self.deletebeams(beams, temp)

        return temp.image_copy()


    def deleteheads(self, heads, img):
        '''Odstraneni not s hlavicek plnych not
        '''
        temp = img.image_copy()
        for head in heads:
            temp.draw_filled_rect(FloatPoint(head.seghead.ul_x - 4, head.seghead.ul_y - 4),
                                  FloatPoint(head.seghead.lr_x + 4, head.seghead.lr_y + 4),
                                  0)
        return temp.image_copy()


    def deleteheadslines(self, heads, img):
        '''Odstraneni not s hlavicek a linek plnych not
        '''
        temp = img.image_copy()
        for head in heads:
            temp.draw_filled_rect(FloatPoint(head.seghead.ul_x - 4, head.seghead.ul_y - 4),
                                  FloatPoint(head.seghead.lr_x + 4, head.seghead.lr_y + 4),
                                  0)
            temp.draw_filled_rect(FloatPoint(head.segline.ul_x, head.segline.ul_y),
                                  FloatPoint(head.segline.lr_x, head.segline.lr_y),
                                  0)
        return temp.image_copy()

    def findlines(self, imgline, img):
        '''Hledani linek v obraze
        '''
        ccc=[]
        ccline = imgline.cc_analysis()
        gauss = signal.gaussian(3, std=0.5)
        gauss = gauss / sum(gauss)
        for i, c in enumerate(ccline):
            if c.height > 20:
                proj = c.projection_cols()
                filt = np.convolve(proj, gauss, 'same')
                ix = np.argmax(filt)
                if (filt[ix] / c.height) > 0.8:
                    ccc.append(img.subimage(Point(c.ul_x + ix - 4, c.ul_y), Point(c.ul_x + ix + 4, c.lr_y)))
        return ccc

    def getcc(self, img):
        '''Analyza metodou spojenych komponent
        '''
        return img.cc_analysis()

    def subcc(self, imgcc, imgsubcc, iter):
        '''spojeni dvou segmentu vnorenych v sobe
        '''
        tempseg = []
        for s in imgsubcc:
            parts = []
            for c in imgcc:
                if s.ul_x <= c.ul_x <= c.lr_x <= s.lr_x and s.ul_y <= c.ul_y <= c.lr_y <= s.lr_y:
                    parts.append(c)
            if parts and tempseg:
                for ti, t in enumerate(tempseg):
                    if s.ul_x <= t.ul_x <= t.lr_x <= s.lr_x and s.ul_y <= t.ul_y <= t.lr_y <= s.lr_y:
                        tempseg[ti] = Seg.combine(parts)
                        parts = []
                        break
            if parts:
                tempseg.append(Seg.combine(parts))
        return tempseg


    def getdots(self, headlist, imgcc, delcc, sf):
        '''detekce tecek
        '''
        for head in headlist:
            head.haveDot(imgcc, sf)

    def getflags(self, headlist, imgcc, delcc, sf):
        '''detekce praporku
        '''
        for head in headlist:
            head.haveFlag(delcc, sf)

    def findbeams(self, heads, orig):
        '''detekce tramcu
        '''
        beams = []
        offset = 15
        seg = orig.cc_analysis()
        for c in seg:
            if (c.width>50 and c.height>50):
                b = Beams(heads, c)
                if b.beam:
                    beams.append(b)
        for beam in beams:
            if (len(beam.beam) > 1):
                for part in beam.beam:
                        sub = orig.subimage(Point(part.ul_x, part.ul_y),
                                            Point(part.lr_x, part.lr_y))
                        projsub = sub.projection_cols()
                        part.setLenght(projsub[0])
        return beams