#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 
# Copyright 2014 <+YOU OR YOUR COMPANY+>.
# 
# 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 scipy.ndimage.filters import uniform_filter1d

class sch_receiver():
    """
    docstring for class sch_reciever
    """
    def __init__(self, OSR):
        self.sync_seq = array([1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0,
                               0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
                               0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1,
                               0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1])
        self.OSR = OSR
        sync_seq_msk_tmp = self.msk_mod(self.sync_seq, -1j)
        self.sync_seq_msk = sync_seq_msk_tmp[5:59]
        self.sync_seq_msk_interp = zeros(self.OSR*len(self.sync_seq_msk), dtype=np.complex64)
        self.sync_seq_msk_interp[::OSR] = self.sync_seq_msk
        self.L = 5

    def msk_mod(self, x, start_point):
        x_nrz = 2*x-1 
        x_diffenc = x_nrz[1:]*x_nrz[0:-1]
        mod_tmp = concatenate((array([start_point]),1j*x_diffenc))
        return cumprod(mod_tmp)
    
    def get_chan_imp_resp(self, sch_burst):
        sch_burst_bl = resize(array(sch_burst), (int(len(sch_burst)/self.OSR),self.OSR))
        correlation_bl = zeros(shape(sch_burst_bl), dtype=np.complex64)
        for ii in xrange(0,self.OSR):
            correlation_bl[:,ii]=correlate(sch_burst_bl[:,ii],self.sync_seq_msk,'same')
        
        correlation_bl = correlation_bl/len(self.sync_seq_msk)
        power_bl_mov_avg = uniform_filter1d(abs(correlation_bl)**2,5,mode='constant',axis=0)

        print "correlation_bl.argmax()",argmax(abs(hstack(correlation_bl)))
        print "power_bl_mov_avg.argmax()",hstack(power_bl_mov_avg).argmax()
        print 'unravel_index(correlation_bl.argmax(), correlation_bl.shape)',unravel_index(correlation_bl.argmax(), correlation_bl.shape)
        print 'unravel_index(power_bl_mov_avg.argmax(), power_bl_mov_avg.shape)',unravel_index(power_bl_mov_avg.argmax(), power_bl_mov_avg.shape)
#        correlation = zeros(shape(sch_burst))
#        correlation = correlate(sch_burst, self.sync_seq_msk_interp,'same')/len(self.sync_seq_msk)
#        print "pozycja maksimum",argmax(abs(correlation))
        plot(abs(hstack(correlation_bl))*1000)
#        hold(True)
#        plot(abs(sch_burst)*500)
#        print shape(range(0,len(sch_burst),self.OSR))
#        print shape(correlation_bl[:,0])
        for ii in range(0,self.OSR):
            plot(range(ii,len(correlation_bl[:,0])*self.OSR,self.OSR),power_bl_mov_avg[:,ii]*5e6,'r.')
        show()
    def receive(self, input_corr, chan_imp_resp):
        pass

class sch_detector(gr.sync_block):
    """
    docstring for block sch_detector
    """
    def __init__(self, OSR):
        gr.sync_block.__init__(self,
            name="sch_detector",
            in_sig=[complex64],
            out_sig=[complex64])
        self.OSR = OSR
        self.states = {"waiting_for_fcch_tag":1, "reaching_sch_burst":2, "sch_at_input_buffer":3}
        self.state = self.states["waiting_for_fcch_tag"]
        self.sch_offset = -100 #-100 - just some invalid value of sch burst position in the stream
        self.burst_size = int(round(156.25*self.OSR))
        self.guard_period = int(round(8.25*self.OSR))
        self.block_size = self.burst_size + self.guard_period
        self.set_history(self.block_size)
        self.set_output_multiple(self.guard_period)
        self.sch_receiver = sch_receiver(OSR)
        
    def work(self, input_items, output_items):
        in0 = input_items[0]
        out = output_items[0]
        to_consume = len(in0)-self.history()
        
        if self.state == self.states["waiting_for_fcch_tag"]:
            fcch_tags = []
            
            start = self.nitems_written(0)
            stop = start + len(in0)
            key = pmt.string_to_symbol("fcch")
            fcch_tags = self.get_tags_in_range(0, start, stop, key)
            if fcch_tags:
                self.sch_offset = fcch_tags[0].offset + int(round(8*self.burst_size+0*self.guard_period)) #156.25 is number of GMSK symbols per timeslot, 
                                                                                       #8.25 is arbitrary safety margin in order to avoid cutting boundary of SCH burst
                self.state = self.states["reaching_sch_burst"]
            
        elif self.state == self.states["reaching_sch_burst"]:
            samples_left = self.sch_offset-self.nitems_written(0)
            if samples_left <= len(in0)-self.history():
                to_consume = samples_left
                self.state = self.states["sch_at_input_buffer"]

        elif self.state == self.states["sch_at_input_buffer"]:
            offset = self.nitems_written(0)
            key = pmt.string_to_symbol("sch")
            value =  pmt.from_double(0)
            self.add_item_tag(0,offset, key, value)
            self.state = self.states["waiting_for_fcch_tag"]
            self.sch_receiver.get_chan_imp_resp(in0[0:self.block_size+self.guard_period])
#            plot(unwrap(angle(in0[0:2*self.block_size])))
#            show()

        out[:] = in0[self.history()-1:]
        return to_consume

