#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 
# Copyright 2014 Piotr Krysik pkrysik@elka.pw.edu.pl
# 
# This 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 3, or (at your option)
# any later version.
# 
# This software 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 software; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
# 

from numpy import *
from pylab import *
from gnuradio import gr
import pmt
from gsm.chirpz import ZoomFFT

class fcch_burst_tagger(gr.sync_block):
    """
    docstring for block fcch_burst_tagger
    """
    def __init__(self, OSR):
        gr.sync_block.__init__(self,
            name="fcch_burst_tagger",
            in_sig=[complex64, float32],
            out_sig=[complex64])

        self.state=False
        self.symbol_rate = 1625000/6
        self.OSR=OSR
        self.samp_rate = self.symbol_rate*OSR
        self.burst_size = int(156.25*self.OSR)
        self.guard_period = int(round(8.25*self.OSR))
        self.block_size = self.burst_size+self.guard_period
        self.processed_block_size = int(142*self.OSR)
        self.set_history(self.burst_size)
        self.set_output_multiple(self.guard_period)
        self.prev_offset=0
        
        #parameters of zoomfft frequency estimator
        f1 = self.symbol_rate/4*0.9
        f2 = self.symbol_rate/4*1.1
        m=5000*self.OSR
        self.zoomfft = ZoomFFT(self.processed_block_size, f1, f2, m, Fs=self.samp_rate)
        self.f_axis = linspace(f1,f2,m)

    def work(self, input_items, output_items):
        in0=input_items[0]
        output_items[0][:] = in0[self.history()-1:]

        threshold = input_items[1][self.history()-1:]
        threshold_diff = diff(concatenate([[0],threshold]))
        up_to_high_indexes = nonzero(threshold_diff>0)[0]

        up_to_high_idx=[] 
        
        for up_to_high_idx in up_to_high_indexes:           #look for "high" value at the trigger
            if up_to_high_idx==0 and self.state==True:    #if it's not transition from "low" to "high"
                continue                                    #then continue
            self.state=True                               #if found - change state
        
        if self.state==True and up_to_high_idx and any(threshold_diff<0):          #and look for transition from high to low
            last_up_to_high_idx = up_to_high_idx
            last_high_to_low_idx = nonzero(threshold_diff<0)[0][-1]
            
            if last_high_to_low_idx-last_up_to_high_idx>0:
                coarse_idx = int(last_high_to_low_idx+self.history()-self.guard_period-self.burst_size)
                inst_freq = angle(in0[coarse_idx:coarse_idx+self.block_size]*in0[coarse_idx-self.OSR:coarse_idx+self.block_size-self.OSR].conj())/(2*pi)*self.symbol_rate #instantaneus frequency estimate
                precise_idx = self.find_best_position(inst_freq)
#                measured_freq = mean(inst_freq[precise_idx:precise_idx+self.processed_block_size])
                expected_freq = self.symbol_rate/4
                zoomed_spectrum = abs(self.zoomfft(in0[coarse_idx+precise_idx:coarse_idx+precise_idx+self.processed_block_size]))
                measured_freq = self.f_axis[argmax(zoomed_spectrum)]
                freq_offset = measured_freq - expected_freq
                offset = self.nitems_written(0) + coarse_idx + precise_idx - self.guard_period
                key = pmt.string_to_symbol("fcch")
                value =  pmt.from_double(freq_offset)
                self.add_item_tag(0,offset, key, value)
                self.state=False

#   Some additional plots and prints for debugging
#                print "coarse_idx+precise_idx",coarse_idx+precise_idx
#                print "offset-self.nitems_written(0):",offset-self.nitems_written(0)
                print offset-self.prev_offset
                self.prev_offset=offset
                print "freq offset", freq_offset
#                freq_offset = measured_freq - expected_freq
#                plot(self.f_axis, zoomed_spectrum)
#                show()
#                plot(inst_freq[precise_idx:precise_idx+self.burst_size])
#                show()
#                plot(unwrap(angle(in0[coarse_idx+precise_idx:coarse_idx+precise_idx+self.burst_size])))
#                show()
#                
        return len(output_items[0])

    def find_best_position(self, inst_freq):
        lowest_max_min_diff = 1e6 #1e6 - just some large value
        start_pos = 0
        
        for ii in xrange(0,int(30*self.OSR)):
            min_inst_freq = min(inst_freq[ii:self.processed_block_size+ii-1]);
            max_inst_freq = max(inst_freq[ii:self.processed_block_size+ii-1]);

            if (lowest_max_min_diff > max_inst_freq - min_inst_freq):
                lowest_max_min_diff = max_inst_freq - min_inst_freq;
                start_pos = ii
#                print 'start_pos',start_pos
        
#        plot(xrange(start_pos,start_pos+self.processed_block_size),inst_freq[start_pos:start_pos+self.processed_block_size],'r.')
#        hold(True)
#        plot(inst_freq)
#        show()
        
        return start_pos
