from gamera.core import *
from OMRnotes.scripts.classification.dist import Distance
from OMRnotes.scripts.classification.head import *
from OMRnotes.scripts.classification.halfhead import Halfheads
from tests.old_version.beam import Beams
from OMRnotes.scripts.classification.seg import Seg
from OMRnotes.scripts.classification.searcher import Searcher2
from scipy import signal
import numpy as np


def findhalfheads(lin, img, sf):
    '''Hledani pulovych not
    
    vstup:
    
    lin - segmenty linek
    
    img - obrazek s odstranenymi linkami
    
    sf - informace o odstranenych linkach
    
    vystup:
    
    halfheadlist - vystupni list pulovych not
    
    Funkce je schopna detekovat roztristene segmenty pulovych not.
    Kolem linek hleda osamocene segmenty v maximalni velikosti dvojnasobku mezery
    a vzdalenosti od vrchu nebo spodu linek. Vice nalezanych segmentu je spojeno a 
    rozmerny spojeni jsou otestovany v ruznych kombinacich. Odfiltrovany jsou male
    a prilis velke spojene segmenty. Validni kombinakce je ulozena do seznamu.
    --Tato funkce je ve vyvoji 
    '''
    imgcc = img.cc_analysis()
    dist = Distance(lin, imgcc)
    headlist = []
    headlistall = []
    halfheadlist = []
    for i, d in enumerate(dist.data):
        for j, item in enumerate(d):
            # compact = imagedelcc[j].compactness()
            if ( \
                                        (imgcc[j].width < (sf.staffspace_height * 2)) and (
                                        imgcc[j].height < (sf.staffspace_height * 2)) \
                                        and (imgcc[j].ul_x > lin[i].ul_x - 40) and (imgcc[j].ul_y > lin[i].ul_y - 40) \
                                and (imgcc[j].lr_x < lin[i].lr_x + 40) and (imgcc[j].lr_y < lin[i].lr_y + 40) \
                    # and (compact[0] > 0.10) and (compact[0] < 0.35) \
            ):
                if (((item[11] < 0) and item[10] < lin[i].height / 2)):
                    headlistall.append(Halfheads(j, i, imgcc[j], lin[i], item[10], 1))
                    head = [headi for headi, x in enumerate(headlist) if x.index2 == i]
                    if not head:
                        headlist.append(Halfheads(j, i, imgcc[j], lin[i], item[10], 1))
                    else:
                        if headlist[head[0]].distance > item[10]:
                            headlist[head[0]].distance = item[10]
                            headlist[head[0]].segline = lin[i]
                            headlist[head[0]].dir = 1
                if (((item[9] > 0) and item[8] < lin[i].height / 2)):
                    headlistall.append(Halfheads(j, i, imgcc[j], lin[i], item[8], 2))
                    head = [headi for headi, x in enumerate(headlist) if x.index2 == i]
                    if not head:
                        headlist.append(Halfheads(j, i, imgcc[j], lin[i], item[8], 2))
                    else:
                        if headlist[head[0]].distance > item[8]:
                            headlist[head[0]].distance = item[8]
                            headlist[head[0]].segline = lin[i]
                            headlist[head[0]].dir = 2

    for head in headlist:
        headx = [x for x in headlistall if ((x.index2 == head.index2) and (x.dir == head.dir))]
        halfheadpartlist = []
        for headpart in headx:
            segment = Seg.combine([head.seghead, headpart.seghead])
            if ((segment.width < (sf.staffspace_height * 2.0)) and (segment < (sf.staffspace_height * 1.5))):
                halfheadpartlist.append(headpart)
        if halfheadpartlist:
            fullseg = Seg.combine([h.seghead for h in halfheadpartlist])
            if ((fullseg.width > (sf.staffspace_height * 1)) and (fullseg.height > (sf.staffspace_height * 1))):
                halfheadlist.append(Halfheads(head.index1, head.index2, fullseg, head.segline, head.distance, head.dir))
    return halfheadlist