# -*- coding: utf-8 -*-
"""User-friendly top-level functions which allow the user to handle 
    
#. Call-background segmentation
#. CF-FM call part segmentation
#. Measurement of CF-FM audio parts 

Let's take a look at an example where we [TO BE COMPLETED!!!]

.. code-block:: python

    import scipy.signal as signal 
    from itsfm.user_interface import segment_and_measure_call
    from itsfm.view_horseshoebat_call import *
    from itsfm.simulate_calls import make_cffm_call

    # create synthetic call 
    call_parameters = {'cf':(100000, 0.01),
                        'upfm':(80000, 0.002),
                        'downfm':(60000, 0.003),
                        }
    
    fs = 500*10**3 # 500kHz sampling rate 
    synthetic_call, freq_profile = make_cffm_call(call_parameters, fs) 

    # window and reduce overall signal level
    synthetic_call *= signal.tukey(synthetic_call.size, 0.1)
    synthetic_call *= 0.75
    
    # measuring a well-selected call (without silent background)
    
    
    
    # measuing a call with a silent background
    
    # and add 2ms of additional background_noise of ~ -60dBrms
    samples_1ms = int(fs*0.001)
    final_size = synthetic_call.size + samples_1ms*2
    call_with_noise = np.random.normal(0,10**(-60/20.0),final_size)
    call_with_noise[samples_1ms:-samples_1ms] += synthetic_call
    
    # 
    
    seg_and_msmts = segment_and_measure_call(call_with_noise, fs,
                                             segment_from_background=True)
    call_segmentation, call_parts, measurements, backg_segment = seg_and_msmts

"""

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.backends.backend_pdf
import itsfm.segment 
from itsfm.segment import segment_call_from_background
from itsfm.segment import segment_call_into_cf_fm
from itsfm.measure import measure_hbc_call
from itsfm.measure import parse_cffm_segments

def segment_and_measure_call(main_call, fs,
                             segment_from_background=False, 
                             **kwargs):
    '''Segments the CF and FM parts of a call and then 
    proceeds to measure their characteristics. If required, 
    also segments call from background. 

    Parameters
    ----------
    main_call : np.array
    fs : float>0
        sampling rate in Hz
    segment_from_background : boolean
        Whether to segment the call in the main_call audio. 
        Defaults to False.

    Keyword Arguments
    -----------------
    For further keyword arguments see segment_call_from_background,
    segment_call_into_cf_fm and measure_hbc_call

    Returns
    -------
    segmentation_outputs : tuple
        The outputs of segment_call_into_cf_fm in a tuple
    call_parts_audio : dictionary
        Dictionary with numbered entries. If a sound has the following
        order of Cf and FM: FM-CF-FM, then the keys will be 
        'fm1','cf1','fm2'. The numbering is according to the chronological 
        order. 
    measurements : pd.DataFrame
        All the measurements from the FM and CF parts. 

    Example
    -------
    Let's simulate a call to demonstrate how the measurement+segmentation
    works. 
    
    >>> import scipy.signal  as signal 
    >>> from itsfm.simulate_calls import make_cffm_call
    >>> call_properties = {'cf':(80000, 0.01), 'upfm':(70000, 0.002),
                           'downfm':(50000, 0.002)}
    >>> fs = 500000
    >>> call, profile = make_cffm_call(call_properties, fs)
    >>> call *= signal.tukey(call.size, 0.1)
    >>> plt.figure()
    >>> plot1 = plt.subplot(211)
    >>> plt.plot(profile)
    >>> #segment the CF and FM parts with the default 'peak percentage' method. 
    >>> segm_out, call_parts, measures, _ = segment_and_measure_call(call,
                                                                    fs,
                                                                    segment_method='peak_percentage',
                                                                    peak_percentage=0.999,
                                                                    window_size=int(fs*0.5*10**-3))
    >>> print(measures)

    Now segment with frequency tracking implemented with the Pseudo Wigner Ville
    Distribution, and the set the fmrate threshold to 10 kHz/ms
    
    >>> segm_out, call_parts, measures, _ = segment_and_measure_call(call,
                                                                     fs,
                                                                     segment_method='pwvd',
                                                                     fmrate_threshold=10,
                                                                     medianfilter_length=0.5*10**-3,
                                                                     )
    >>> plt.subplot(212, sharex=plot1)
    >>> plt.plot(segm_out[-1]['fmrate'])
    >>> print(measures)

    See Also
    --------
    itsfm.measure

    '''
    cf, fm, info = segment_call_into_cf_fm(main_call, fs, 
                                                           **kwargs)

    measurements = measure_hbc_call(main_call, fs, cf, fm, 
                                                        **kwargs)
    call_segments = parse_cffm_segments(cf,fm)
    
    call_parts_audio = {}
    for (part_name, location) in call_segments:
        call_parts_audio[part_name] = main_call[location]

    return (cf, fm, info), call_parts_audio, measurements

def save_overview_graphs(all_subplots, analysis_name, file_name, index,
                          **kwargs):
    '''Saves overview graphs. 

    Parameters
    ----------
    all_subplots : list
        List with plt.subplot objects in them. 
        For each figure to be saved, one subplot object is enough.
    analysis_name : str
        The name of the analysis. If this funciton is called 
        through a batchfile, then it becomes the name of the 
        batchfile
    file_name : str
    index : int, optional
        A numeric identifier for each graph. This is especially relevant
        for analyses driven by batch files as there may be cases where the 
        calls are selected from the same audio file but in different parts. 

    Returns
    -------
    None
    
    Notes
    -----
    This function has the main side effect of saving all the input figures
    into a pdf file with >1 pages (one page per plot) for the user to inspect 
    the results.
    
    Example
    ---------
    import numpy as np 
    
    # 1st plot
    plt.figure()
    a = plt.subplot(211)
    plt.plot([1,2,3])
    b = plt.subplot(212)
    plt.plot([5,4,3])
    
    #2nd plot
    plt.figure()
    c = plt.subplot(121)
    plt.plot(np.random.normal(0,1,100))
    d = plt.subplot(122)
    plt.plot(np.random.normal(0,1,10))
    
    save_overview_graphs([a,c], 'example_plots', 'example_file',0)
    '''
    
    final_file_name = analysis_name+'_'+file_name+'_'+str(index)
        
    # thanks to J0e3gan : https://stackoverflow.com/a/17788764
    pdf = matplotlib.backends.backend_pdf.PdfPages(final_file_name+".pdf")
    
    for one_subplot in all_subplots: 
        pdf.savefig(one_subplot.figure)
    pdf.close()

