from OMRnotes.scripts.classification.dist import Distance
from OMRnotes.scripts.classification.dot import Dot
from OMRnotes.scripts.classification.seg import Seg
from OMRnotes.scripts.classification.lines import Lines
import numpy as np
from scipy import signal

class Quaters():
    '''Datova struktura pro vsechny harmonicky spojene
    hlavicky not
    '''
    def __init__(self, lines):
        self.quaters = []
        self.lines = lines
        pass

    def __getitem__(self, i):
        return self.quaters[i]

    def append(self, heads):
        '''Test slouceni hlavicek not do harmonicke podoby
        
        Tesetuje, zda hlavicky nalezi stejne lince
        '''
        adder = False
        linefind = self.lines.finder(heads.seghead.center_y)
        if (heads.seghead.center_x > (linefind[0] + 50)):
            for i, h in enumerate(self.quaters):
                if (abs(h.segline.ul_x - heads.segline.ul_x) < 10
                    and (abs(h.segline.ul_y - heads.segline.ul_y) < 10
                        or abs(h.segline.ul_y - heads.segline.lr_y) < 10
                        or abs(h.segline.lr_y - heads.segline.lr_y) < 10
                        or abs(h.segline.lr_y - heads.segline.ul_y) < 10)
                    ):
                    if h.dir == heads.dir:
                        self.quaters[i].addnote(heads)
                        adder=True
                        print "addnote OK"
                        break
                    else:
                        print "addnote direction problem"
                        break
            if not adder:
                self.quaters.append(heads)
        else:
            print "addnote outline problem"


class Head:
    '''Hlavicka noty
    '''
    def __init__(self, head, center_x, center_y, pitch):
        self.head = head
        self.center_x = center_x
        self.center_y = center_y
        self.pitch = pitch


class Heads(Dot):
    '''Harmonicky spojene hlavicky not.
    
    Vypocitava linku, ktere nota nalezi, podle toho je indexovana
    
    Index 0 znaci posledni linku
    
    O pultonu nize je index -1
    
    O pultonu vyse je index 1
    '''
    def __init__(self, index1, index2, seghead, segline, distance, dir, lines, dur):
        self.index1 = index1
        self.index2 = index2
        self.segheadlist = []
        self.dur = dur
        self.segline = segline
        self.distance = distance
        self.dir = dir
        self.multinote = False
        self.flag = None
        self.dot = None
        self.duration = 0
        self.lines = lines
        if dir == 1:
            touchline = lines.touch([segline.ul_x, segline.ul_y])
        elif dir == 2:
            touchline = lines.touch([segline.lr_x, segline.lr_y])
        for head in seghead:
            factor = (lines.staffline_height + lines.staffspace_height)
            numheads = np.round(head.nrows / factor)
            if numheads == 0:
                numheads = 1
            for x in range(1, numheads*2, 2):
                center_y = (head.nrows / (2*numheads))*x
                touchhead = lines.touch([head.center_x, head.ul_y + center_y], touchline[0])
                plin = 2*((lines.linenum-1) - touchhead[1])
                pudlin = -round(2*touchhead[2] / factor)

                self.segheadlist.append(Head(head, head.center_x, center_y, plin + pudlin))
        self.staves = touchline[0]
        self.seghead = Seg.combine(seghead)

    def addnote(self, seghead):
        '''Spoji hlavicky do harmocicke podoby
        '''
        self.dur = max([self.dur, seghead.dur])
        #self.flag = max([self.flag, seghead.flag])
        #self.dot = max([self.dot, seghead.dot])
        self.segline = Seg.combine([self.segline, seghead.segline])
        for sh in seghead.segheadlist:
            self.segheadlist.append(sh)
        self.seghead = Seg.combine([h.head for h in self.segheadlist])

    def isBeam(self, seg):
        '''Testuje, zda se hlavicka s linkou dotykaji
        '''
        distnot = Distance([self.segline], [seg])
        for j, item in enumerate(distnot.data):
            if (item[0][2]):
                return True
        return []

    def addHead(self, seghead):
        '''Pridava spravne detekovanou hlavicku do seznamu harmonickych spojeni
        '''
        self.segheadlist.append(seghead)
        self.seghead = Seg.combine([h.head for h in self.segheadlist])

    def haveFlag(self, imgseg, sf):
        '''Testuje zda nota ma praporek
        '''
        distnoline = Distance([self.segline], imgseg)
        for j, item in enumerate(distnoline.data[0]):
            if ((self.segline.ul_x < imgseg[j].ul_x) and ((self.segline.ul_x + 38) > imgseg[j].lr_x) \
                        and ((self.segline.ul_y - 20) < imgseg[j].ul_y) and ((self.segline.lr_y + 20) > imgseg[j].lr_y) \
                ):
                if self.flag is None:
                    self.flag = Seg(self.segline.ul_x, imgseg[j].ul_y, imgseg[j].lr_x, imgseg[j].lr_y)
                else:
                    if self.flag.lr_x < imgseg[j].lr_x:
                        self.flag.lr_x = imgseg[j].lr_x
                    if self.flag.ul_y > imgseg[j].ul_y:
                        self.flag.ul_y = imgseg[j].ul_y
                    if self.flag.lr_y < imgseg[j].lr_y:
                        self.flag.lr_y = imgseg[j].lr_y
        if not (self.flag is None):
            if (self.flag.width < 15 or self.flag.height < 15):
                self.flag = None