#
#coding=utf-8
#Copyright (C) 2015 Barcelona Science
#
#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
'''
:copyright: Copyright (C) 2015 Barcelona Science
:authors: L.M. de Vries, A. Nardi
:contact: enric.vazquez@idaea.csic.es
:license: GPL General Public License, version 2 or any later version (http://opensource.org/licenses/GPL-2.0)
'''
from collections import OrderedDict
import matplotlib
import matplotlib.pyplot as plt
from PyQt4 import QtGui
import sys
from datetime import datetime

from ChemPlot import ChemPlot
from ChemPlot import CPSETTINGS
from ChemPlot import LINESERIES

class TIMEPLOTFORMAT():    
    time = "time"
    day_time = "day-time"
    month_day = "month-day"
    month_day_time = "month-day-time"
    year = "year"
    year_month = "year-month"
    year_month_day = "year-month-day"
    year_month_day_time = "year-month-day-time"

    name = {}    
    name[time]='%H:%M'
    name[day_time]='%d %H:%M'
    name[month_day]='%m-%d'
    name[month_day_time]='%m-%d %H:%M'
    name[year]='%Y'
    name[year_month]='%Y-%m'
    name[year_month_day]='%Y-%m-%d'
    name[year_month_day_time]='%Y-%m-%d %H:%M'    

class TIMEPLOTSETTINGS():        
    time = "time"    
    time_automatic_title_id = "time_automatic_title"
    time_automatic_title_text_id = "time_automatic_title_text_id"    
    time_format_id = "time_format"
    
    default_settings = OrderedDict({
                    time:{
                        time_automatic_title_id:{
                            CPSETTINGS.value_key:True,
                            CPSETTINGS.label_key:"time_automatic_title_id",
                            CPSETTINGS.type_value_key:"bool"
                        },
                        time_automatic_title_text_id:{
                            CPSETTINGS.value_key:"auto title",
                            CPSETTINGS.label_key:"time_automatic_title_text_id",
                            CPSETTINGS.type_value_key:"str"
                        },                          
                        time_format_id:{
                            CPSETTINGS.value_key: 'year-month-day',
                            CPSETTINGS.label_key:"Show labels",
                            CPSETTINGS.type_value_key:"str"
                        }
                    }
                })

class TimeSerie(object):  
    def __init__(self, name, data):
        self.parameterName = data["parameterName"]
        self.point = data["point"]        
        self.dates = []
        for curDate in data["dates"]:
            myTime = datetime.strptime(curDate, "%Y-%m-%d %H:%M:%S.%f")
            self.dates.append(myTime) 
        self.values = data["values"]
        self.samples = data["samples"]
        self.label = self.point +"_" + self.parameterName

class TimePlot(ChemPlot):
    '''
    This class implements the Time Plot.
    '''
    def __init__(self, parent=None):       
        super(TimePlot, self).__init__(parent)

        self.legendPosition = 'timePlotLegend'  
        self.set_setting(CPSETTINGS.title, CPSETTINGS.title_label_id, 'Time Plot')
        self.set_setting(CPSETTINGS.window, CPSETTINGS.window_title_id, 'Time Plot')      
        self.set_setting(CPSETTINGS.line_plot, CPSETTINGS.line_width_id, 2.0)
        self.set_setting(CPSETTINGS.line_plot, CPSETTINGS.line_type_serie_id, LINESERIES.solid) 
        
        self.m_settings.update(TIMEPLOTSETTINGS.default_settings)     
        
        
    def setData(self, data):
        #=======================================================================
        #          'series': {
        #                     u'P1_900': {
        #                                 'parameterName': u'nitrates', 
        #                                 'dates': [u'1996-12-19 00:00:00.000', u'1997-10-29 00:00:00.000'], 
        #                                 'values': [89.4, 45.8], 
        #                                 'samples': [u'P1_CUP9612-012', u'P1_CUP9710-010'], 
        #                                 'point': u'P1'}}, 
        #          'title': u'Measurements (ppm)', 
        #          'parameterIds': [900], 
        #          'datesLabel': 'time', 
        #          'valuesLabel': u'ppm'}
        #          
        #=======================================================================
        self.series = []
        self.labels = []
        for curSerie in data["series"]:
            newSerie = TimeSerie(curSerie, data["series"][curSerie])
            self.series.append(newSerie)
            self.labels.append(newSerie.label)
            
        self.set_setting(TIMEPLOTSETTINGS.time, TIMEPLOTSETTINGS.time_automatic_title_text_id, data["title"])
        self.parameterIds = data["parameterIds"]
        self.datesLabel = data["datesLabel"]
        self.valuesLabel = data["valuesLabel"]
        
    def pre_processing(self):
        plt.ylabel(self.valuesLabel, fontsize=16)
        self.ax.xaxis.grid(which='minor', color='0.65', linewidth=1, linestyle='--', alpha=1.0)
        self.ax.grid()
        
        is_time_automatic_title = self.setting(TIMEPLOTSETTINGS.time, TIMEPLOTSETTINGS.time_automatic_title_id)
        if is_time_automatic_title:
            auto_title = self.setting(TIMEPLOTSETTINGS.time, TIMEPLOTSETTINGS.time_automatic_title_text_id)
            self.set_setting(CPSETTINGS.title, CPSETTINGS.title_label_id, auto_title)
    
    def plot_values(self):    
        curPoint = 0
        for serie in self.series:            
            dates = serie.dates
            values = serie.values     
            label = serie.label           
            self.private_plot(dates, values, label, curPoint, date_plot=True)
            curPoint += 1
        timeFormat = TIMEPLOTFORMAT.name[self.setting(TIMEPLOTSETTINGS.time, TIMEPLOTSETTINGS.time_format_id)]
        self.ax.xaxis.set_major_formatter( matplotlib.dates.DateFormatter(timeFormat) )
        self.ax.fmt_xdata = matplotlib.dates.DateFormatter('%Y-%m-%d %H:%M:%S')        
        self.fig.autofmt_xdate(rotation=45)
    
    def post_processing(self):
        x_min, xmax = self.ax.get_xlim()
        x_size = xmax-x_min
        margin = x_size/25
        self.ax.set_xlim(x_min-margin, xmax+margin)

def plotLinePlot1():
    
    plot = TimePlot()    
    
    data = {74: {'series': {u'P5_415': {'parameterName': u'calcium', 'dates': [u'2003-01-28 00:00:00.000'], 'values': [207.6], 'samples': [u'P5_CCL0301'], 'point': u'P5'}, u'P3_1047': {'parameterName': u'sodium', 'dates': [u'2003-01-29 00:00:00.000'], 'values': [142.5], 'samples': [u'P3_CCL0301'], 'point': u'P3'}, u'P3_814': {'parameterName': u'magnesium', 'dates': [u'2003-01-29 00:00:00.000'], 'values': [53.6], 'samples': [u'P3_CCL0301'], 'point': u'P3'}, u'P5_1047': {'parameterName': u'sodium', 'dates': [u'2003-01-28 00:00:00.000'], 'values': [152.1], 'samples': [u'P5_CCL0301'], 'point': u'P5'}, u'P5_814': {'parameterName': u'magnesium', 'dates': [u'2003-01-28 00:00:00.000'], 'values': [68.6], 'samples': [u'P5_CCL0301'], 'point': u'P5'}, u'P3_415': {'parameterName': u'calcium', 'dates': [u'2003-01-29 00:00:00.000'], 'values': [146.4], 'samples': [u'P3_CCL0301'], 'point': u'P3'}}, 'title': u'Measurements (ppm)', 'parameterIds': [814, 1047, 415], 'datesLabel': 'time', 'valuesLabel': u'ppm'}, 54: {'series': {u'P1_414': {'parameterName': u'calcium', 'dates': [u'2006-11-08 00:00:00.000'], 'values': [97.93], 'samples': [u'P1_CUP0611'], 'point': u'P1'}, u'P5_414': {'parameterName': u'calcium', 'dates': [u'2010-05-30 00:00:00.000'], 'values': [117.28], 'samples': [u'P5_CPR1011'], 'point': u'P5'}, u'P1_1046': {'parameterName': u'sodium', 'dates': [u'2006-11-08 00:00:00.000'], 'values': [64.74], 'samples': [u'P1_CUP0611'], 'point': u'P1'}, u'P2_813': {'parameterName': u'magnesium', 'dates': [u'2010-11-24 00:00:00.000'], 'values': [28.01], 'samples': [u'P2_CPR1011'], 'point': u'P2'}, u'P8_1046': {'parameterName': u'sodium', 'dates': [u'2006-10-24 00:00:00.000'], 'values': [144.53], 'samples': [u'P8_CUP0610'], 'point': u'P8'}, u'P4_1046': {'parameterName': u'sodium', 'dates': [u'2010-05-30 00:00:00.000'], 'values': [165.0], 'samples': [u'P4_CPR1011'], 'point': u'P4'}, u'P8_813': {'parameterName': u'magnesium', 'dates': [u'2006-10-24 00:00:00.000'], 'values': [24.99], 'samples': [u'P8_CUP0610'], 'point': u'P8'}, u'P10_813': {'parameterName': u'magnesium', 'dates': [u'2006-10-25 00:00:00.000'], 'values': [28.0], 'samples': [u'P10_CUP0610'], 'point': u'P10'}, u'P3_1046': {'parameterName': u'sodium', 'dates': [u'2006-10-24 00:00:00.000'], 'values': [147.81], 'samples': [u'P3_CUP0610'], 'point': u'P3'}, u'P12_414': {'parameterName': u'calcium', 'dates': [u'2006-12-13 00:00:00.000'], 'values': [129.85], 'samples': [u'P12_CUP0612'], 'point': u'P12'}, u'P4_813': {'parameterName': u'magnesium', 'dates': [u'2010-05-30 00:00:00.000'], 'values': [28.48], 'samples': [u'P4_CPR1011'], 'point': u'P4'}, u'P11_1046': {'parameterName': u'sodium', 'dates': [u'2001-10-24 00:00:00.000'], 'values': [226.1], 'samples': [u'P11_CAG0110-005'], 'point': u'P11'}, u'P3_813': {'parameterName': u'magnesium', 'dates': [u'2006-10-24 00:00:00.000'], 'values': [47.39], 'samples': [u'P3_CUP0610'], 'point': u'P3'}, u'P12_1046': {'parameterName': u'sodium', 'dates': [u'2006-12-13 00:00:00.000'], 'values': [82.96], 'samples': [u'P12_CUP0612'], 'point': u'P12'}, u'P5_1046': {'parameterName': u'sodium', 'dates': [u'2010-05-30 00:00:00.000'], 'values': [156.07], 'samples': [u'P5_CPR1011'], 'point': u'P5'}, u'P7_1046': {'parameterName': u'sodium', 'dates': [u'2006-09-24 00:00:00.000'], 'values': [168.7], 'samples': [u'P7_CUP0609'], 'point': u'P7'}, u'P10_414': {'parameterName': u'calcium', 'dates': [u'2006-10-25 00:00:00.000'], 'values': [134.8], 'samples': [u'P10_CUP0610'], 'point': u'P10'}, u'P10_1046': {'parameterName': u'sodium', 'dates': [u'2006-10-25 00:00:00.000'], 'values': [143.8], 'samples': [u'P10_CUP0610'], 'point': u'P10'}, u'P8_414': {'parameterName': u'calcium', 'dates': [u'2006-10-24 00:00:00.000'], 'values': [126.07], 'samples': [u'P8_CUP0610'], 'point': u'P8'}, u'P11_414': {'parameterName': u'calcium', 'dates': [u'2001-10-24 00:00:00.000'], 'values': [156.2], 'samples': [u'P11_CAG0110-005'], 'point': u'P11'}, u'P3_414': {'parameterName': u'calcium', 'dates': [u'2006-10-24 00:00:00.000'], 'values': [142.59], 'samples': [u'P3_CUP0610'], 'point': u'P3'}, u'P5_813': {'parameterName': u'magnesium', 'dates': [u'2010-05-30 00:00:00.000'], 'values': [26.18], 'samples': [u'P5_CPR1011'], 'point': u'P5'}, u'P2_414': {'parameterName': u'calcium', 'dates': [u'2010-11-24 00:00:00.000'], 'values': [130.68], 'samples': [u'P2_CPR1011'], 'point': u'P2'}, u'P12_813': {'parameterName': u'magnesium', 'dates': [u'2006-12-13 00:00:00.000'], 'values': [49.72], 'samples': [u'P12_CUP0612'], 'point': u'P12'}, u'P7_414': {'parameterName': u'calcium', 'dates': [u'2006-09-24 00:00:00.000'], 'values': [147.9], 'samples': [u'P7_CUP0609'], 'point': u'P7'}, u'P7_813': {'parameterName': u'magnesium', 'dates': [u'2006-09-24 00:00:00.000'], 'values': [32.1], 'samples': [u'P7_CUP0609'], 'point': u'P7'}, u'P1_813': {'parameterName': u'magnesium', 'dates': [u'2006-11-08 00:00:00.000'], 'values': [58.92], 'samples': [u'P1_CUP0611'], 'point': u'P1'}, u'P4_414': {'parameterName': u'calcium', 'dates': [u'2010-05-30 00:00:00.000'], 'values': [122.16], 'samples': [u'P4_CPR1011'], 'point': u'P4'}, u'P2_1046': {'parameterName': u'sodium', 'dates': [u'2010-11-24 00:00:00.000'], 'values': [146.33], 'samples': [u'P2_CPR1011'], 'point': u'P2'}, u'P11_813': {'parameterName': u'magnesium', 'dates': [u'2001-10-24 00:00:00.000'], 'values': [33.0], 'samples': [u'P11_CAG0110-005'], 'point': u'P11'}}, 'title': u'Measurements (mg/l)', 'parameterIds': [813, 1046, 414], 'datesLabel': 'time', 'valuesLabel': u'mg/l'}}
    curPlotData = data[54]          
    plot.setData(curPlotData)
    plot.draw()
        
if __name__ == '__main__':
    
    app = QtGui.QApplication(sys.argv)
    plotLinePlot1()    
    sys.exit(app.exec_())
            
    