var traffic = {
    timeplot:null,
    resizeTimerID:null,
    setup:function(){
        traffic.checkDates();
        traffic.calendarSetup();
        $('#showTraffic').bind('submit', traffic.showData);
    },
    showData:function(myForm){
        myForm.preventDefault();

        var routeName = escape($('#route_name').val());
        var from_ts = traffic.toEpoch($('#from_ts').val());
        var to_ts = traffic.toEpoch($('#to_ts').val());

        if(!routeName){
            $('#my-timeplot').empty().html("<span class='error'>Please select a Route</span>");
        }
        else if(from_ts>to_ts){
            $('#my-timeplot').empty().html("<span class='error'>The 'from' time must be earlier than the 'to' time</span>");
        }
        else{
            var url = $('#showTraffic').attr('action')+'?route='+routeName+'&from='+from_ts+'&to='+to_ts;

            var eventSource = new Timeplot.DefaultEventSource();
            var plotInfo = [
                Timeplot.createPlotInfo({
                    id: 'plot1',
                    dataSource: new Timeplot.ColumnSource(eventSource,1),
                    valueGeometry: new Timeplot.DefaultValueGeometry({
                        gridColor: '#000000',
                        min: 0,
                        max: 10
                    }),
                    timeGeometry: new Timeplot.DefaultTimeGeometry({
                        gridColor: new Timeplot.Color('#000000'),
                        axisLabelsPlacement: 'top'
                    }),
                    lineColor: '#336699',
                    fillColor: '#336699',
                    showValues: true,
                    roundValues: false
                })
            ];

            traffic.timeplot = Timeplot.create(document.getElementById('my-timeplot'), plotInfo);
            traffic.timeplot.loadJSON(url, ',', eventSource,traffic.epochToDate);
            
            $(window).bind('resize', traffic.resize);
        }
    },
    resize:function(){
        if(traffic.resizeTimerID == null){
            resizeTimerID = window.setTimeout(function(){
                traffic.resizeTimerID = null;
                traffic.timeplot.repaint();
            }, 100);
        }
    },
    checkDates: function(){
        var now = new Date();
        if(!$('#from_ts').val()){
            var epoch = traffic.toEpoch(now);
            dayAgo = traffic.toDate(epoch - (24*60*60));
            $('#from_ts').val(dayAgo.format('mmmm, dd yyyy hh:nn:ss'));
        }
        if(!$('#to_ts').val()){
            $('#to_ts').val(now.format('mmmm, dd yyyy hh:nn:ss'));
        }
    },
    calendarSetup: function(){
        Calendar.setup(
            {
                inputField  : 'from_ts',             // ID of the input field
                ifFormat    : '%B, %e %Y %H:%M:%S',  // The date format
                showsTime   : true,                  // Display the time
                button      : 'from_ts'              // ID of the button
            }
        );

        Calendar.setup(
            {
                inputField  : 'to_ts',               // ID of the input field
                ifFormat    : '%B, %e %Y %H:%M:%S',  // The date format
                showsTime   : true,                  // Display the time
                button      : 'to_ts'                // ID of the button
            }
        );
    },
    epochToDate:function(data){
        var newData=[];
        for each(row in data){
            if(row.date){
                var newDate = new Date();
                var mEpoch = parseInt(row.date); 
                if(mEpoch < 10000000000)
                    mEpoch *= 1000; // convert to milliseconds

                newDate.setTime(mEpoch);
                row.date = newDate.format('yyyy-mm-ddThh:nn');
            }
        }
        return data;
    },
    toEpoch: function(dObj){
        var date = new Date();
        date.setTime(Date.parse(dObj));

        var month = date.getMonth();
        var day = date.getDate();
        var year = date.getFullYear();
        var hour = date.getHours();
        var minute = date.getMinutes();
        var second = date.getSeconds();

        var epoch = new Date();
        epoch.setMonth(month,day);
        epoch.setFullYear(year);
        epoch.setHours(hour,minute,second);

       return (epoch.getTime()-epoch.getMilliseconds())/1000;
    },
    toDate: function(eObj){
        var date = new Date();
        var mEpoch = parseInt(eObj); 
        if(mEpoch < 10000000000)
            mEpoch *= 1000; // convert to milliseconds

        date.setTime(mEpoch);
        return date;
    },
    dayNames: new Array(
        'Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'
    ),
    monthNames: new Array(
        'January','February','March','April','May','June','July','August','September','October','November','December'
    )
}

$(document).ready(traffic.setup);

/* Extend Timeplot functions */

/*
 * Mimic the timeplot.loadText function 
 * - Only needed to change eventSource.loadText to eventSource.loadJSON
 */
Timeplot._Impl.prototype.loadJSON=function(url,separator,eventSource,filter){
    if(this._active){
        var tp=this;

        var fError=function(statusText,status,xmlhttp){
            tp.hideLoadingMessage();
            $('#my-timeplot').empty().html("<span class='error'>Failed to load JSON data from "+url+". Error: "+statusText+"</span");
        };

        var fDone=function(xmlhttp){
            try{
                if(xmlhttp.responseText.replace(/(\[|\])/g,'').length>0){
                    eventSource.loadJSON(xmlhttp.responseText,separator,url,filter);
                }
                else {
                    $('#my-timeplot').empty().html("<span class='error'>No data found</span>");
                }
            }catch(e){
                SimileAjax.Debug.exception(e);
            }finally{
                tp.hideLoadingMessage();
            }
        };

        this.showLoadingMessage();
        window.setTimeout(function(){SimileAjax.XmlHttp.get(url,fError,fDone);},0);
    }
}

/*
 * Mimic the eventSource.loadText function 
 * - Do not parse all data, only the JSON value when creating an evt
 * - Parse the JSON into an Object
 */
Timeplot.DefaultEventSource.prototype.loadJSON=function(jsonText,separator,url,filter){
    if(jsonText==null){
        return;
    }

	var data = jsonText.parseJSON();
	
    this._events.maxValues=new Array();
    var base=this._getBaseURL(url);

    var dateTimeFormat='iso8601';
    var parseDateTimeFunction=this._events.getUnit().getParser(dateTimeFormat);

    var added=false;

    if(filter){
        data=filter(data);
    }

    if(data){
        for(var i=0;i<data.length;i++){
            var row=data[i];
            if(row.date){
                var evt=new Timeplot.DefaultEventSource.NumericEvent(
                    parseDateTimeFunction(row.date),
                    this._parseJSONValue(row.value,separator)
                );
                this._events.add(evt);
                added=true;
            }
        }
    }

    if(added){
        this._fire('onAddMany',[]);
    }
}

/*
 * Turn the JSON value into an array so that it can be correctly processed
 * by Timeplot
 */
Timeplot.DefaultEventSource.prototype._parseJSONValue=function(value,separator){
    value=value.replace(/\r\n?/g,'\n');
    var pos=0;
    var len=value.length;
    var line=[];
    while(pos<len){
        var nextseparator=value.indexOf(separator,pos);
        var nextnline=value.indexOf('\n',pos);
        if(nextnline<0)nextnline=len;
        if(nextseparator>-1&&nextseparator<nextnline){
            line[line.length]=value.substr(pos,nextseparator-pos);
            pos=nextseparator+1;
        }else{
            line[line.length]=value.substr(pos,nextnline-pos);
            pos=nextnline+1;
            break;
        }
    }
    if(line.length<0)return;
    return line;
}

/* Date functions */

String.prototype.zf = function(l){ return '0'.string(l - this.length) + this; }
String.prototype.string = function(l){ var s = '', i = 0; while (i++ < l){ s += this; } return s; }
Number.prototype.zf = function(l){ return this.toString().zf(l); }

// the date format prototype
Date.prototype.format = function(f)
{
    if(!this.valueOf())
        return '&nbsp;';

    var d = this;

    return f.replace(/(yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|nn|ss|a\/p)/gi,
        function($1)
        {
            switch ($1.toLowerCase())
            {
            case 'yyyy': return d.getFullYear();
            case 'mmmm': return traffic.monthNames[d.getMonth()];
            case 'mmm':  return traffic.monthNames[d.getMonth()].substr(0, 3);
            case 'mm':   return (d.getMonth() + 1).zf(2);
            case 'dddd': return traffic.dayNames[d.getDay()];
            case 'ddd':  return traffic.dayNames[d.getDay()].substr(0, 3);
            case 'dd':   return d.getDate().zf(2);
            case 'hh':  return d.getHours().zf(2);
            case 'nn':   return d.getMinutes().zf(2);
            case 'ss':   return d.getSeconds().zf(2);
            case 'a/p':  return d.getHours() < 12 ? 'a' : 'p';
            }
        }
    );
}
