#!/usr/bin/env python
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as 
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version. 
#
#  This program is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#  General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
#  USA.
#
#package edu.udo.cs.yale.tools.math;

#import java.util.List;
#import java.util.LinkedList;

#ported from  YALE - Yet Another Learning Environment
#  Copyright (C) 2001-2004
#      Simon Fischer, Ralf Klinkenberg, Ingo Mierswa, 
#          Katharina Morik, Oliver Ritthoff
#      Artificial Intelligence Unit
#      Computer Science Department
#      University of Dortmund
#      44221 Dortmund,  Germany
#  email: yale-team@lists.sourceforge.net
#  web:   http://yale.cs.uni-dortmund.de/java 
#
#  ported from java to python by Martin Dvh (code was already GPL version 2)

class SimplePeakFinder:
    def __init__ (self):
        self.numberOfNeighbours = int(5)
        self.min_threshold = 0.0
        self.findminima=False

    # Returns a list with peaks. 
    def getPeaks(self,neighbours,data,minimum,findminima): #neighbours=number of neighbours which have to be lower then this peak,data=list of numbers,minimum=threshold above which the samples have to be,findminima=False ==> find maximum peaks (tops), findminima=true ==>find minima (drops)
        self.numberOfNeighbours = neighbours
        self.min_threshold=minimum
        #this.False=0 #todo do we need this
        #this.True=1
        #this.max_threshold=maximum
        self.series=data
        if(findminima):
            self.smaller=False
            self.bigger=True
        else:
            self.smaller=True
            self.bigger=False
        #result = new LinkedList()
        result=[] #List()#:new()
        for i in range(0,len(data)):
            if(self.series[i]>self.min_threshold):
                if (self.isPeak(self.series, i)):
                    result.append(i)
        return result

    # Returns 1 if the value for index is an extremum of the given type between the given numbers 
    #  of neighbours. 
    def isPeak(self,series, index):
        ok = False
        current = index
        okValues = 0
        
        # values to left
        while (ok==False):
            current=current -1
            if (current < 0):
                return 0
            if (self.isOk(series, current, index)==False):
                return 0
            okValues=okValues+1
            if (okValues > self.numberOfNeighbours):
                ok = True
        ok = False
        current = index
        okValues = 0;
        # values to right
        while (ok==False):
            current=current+1
            if (current >= len(series)):
                return 0
            if (self.isOk(series, current, index)==False):
                return 0
            okValues=okValues+1
            if (okValues > self.numberOfNeighbours):
                ok = True
        return True


    # In the minimum case this method returns 1, if the current value is bigger than the index value.
    def isOk(self,series, current, index):
        if (series[current] <= series[index]):
            return self.smaller
        else:
            return self.bigger

