general.namespace('SW');

// class ForecastDataManager
(function () {

    // private static
    var _DATA_CACHE = new general.Cache();
    
    var ForecastDataManager = SW.ForecastDataManager = function(){
        /// <summary></summary>
        /// <param name=""></param>
        /// <returns></returns>
        this.onGetDataSuccess = new YAHOO.util.CustomEvent("onGetDataSuccess", this, false, YAHOO.util.CustomEvent.FLAT);
        this.onGetDataFailure = new YAHOO.util.CustomEvent("onGetDataFailure", this, false, YAHOO.util.CustomEvent.FLAT);
    };
    ForecastDataManager.prototype.constructor = ForecastDataManager;
    
    
    ForecastDataManager.prototype.getRegionData = function(region, startDate) {
        /// <summary>gets forecast data for a region</summary>
        /// <param name="region">object:</param>
        /// <param name="startDate">date:</param>
        /// <returns></returns>
        this._getForecastData(
            '/WebServices/DataPoints.asmx/GetForecastDataCollectionForRegionByDateRange',
            '{"regionId":' + region.regionId + ',"startDate":"' + general.dateFormat(startDate, general.dateFormat.masks.isoDate) + '","numDays":7}',
            region.name,
            startDate,
            "region",
            region.regionId
        );
    };
    
    ForecastDataManager.prototype.getSurfSpotData = function(dataPointId, name, startDate) {
        /// <summary>gets forecast data for a region</summary>
        /// <param name="region">object:</param>
        /// <param name="startDate">date:</param>
        /// <returns></returns>
        this._getForecastData(
            '/WebServices/DataPoints.asmx/GetForecastDataCollectionForSurfSpotByDateRange',
            '{"dataPointId":' + dataPointId + ',"startDate":"' + general.dateFormat(startDate, general.dateFormat.masks.isoDate) + '","numDays":7}',
            name,
            startDate,
            "surfSpot",
            dataPointId
        );
    };

    ForecastDataManager.prototype._getForecastData = function(url, postBody, title, startDate, type, id) {
        /// <summary>general function for getting data</summary>
        /// <param name="url">string: location of webservice</param>
        /// <param name="postBody">string: json string of all args that webservice needs</param>
        /// <param name="title">string: name of item we are getting data for</param>
        /// <param name="startDate">date:</param>
        /// <param name="type">string: the type of data (ie, "region", "surfspot")</param>
        /// <param name="id">int: the unique id of the type</param>
        /// <returns>void</returns>
        
        // get from cache
        var dataFromCache = _DATA_CACHE.get([type, id, startDate]);
        
        if (dataFromCache) {
            this.onGetDataSuccess.fire(dataFromCache);
        }
        else {
            var cObj = YAHOO.util.Connect.asyncRequest(
                'POST',
                url + '?r=' + general.rand(),
                // callback object
                {
                    argument: {"title":title, "startDate":startDate, "type":type, "id":id},
                    success: this._getDataSuccess, 
                    failure: this._getDataFailure, 
                    scope: this
                }, 
                // POST body
                postBody
            );
        }
    };

    ForecastDataManager.prototype.prepData = function(data, startDate, title) {
        // expand spectral
        if (data && data.VirtualBuoyData && data.VirtualBuoyData.Spectral) {
            data.VirtualBuoyData.Spectral = _expandCollapsedSpectralData(data.VirtualBuoyData.Spectral);
        }
        data.startDate = startDate;
        data.title = title;
        data.startDateIsoFormatted = general.dateFormat(data.startDate, general.dateFormat.masks.isoDate);
        return data;
    };

    ForecastDataManager.prototype._getDataSuccess = function(response) {
        var forecastDataCollection = general.deserializeJSON(response.responseText);

        if (forecastDataCollection) {
            data = this.prepData(forecastDataCollection, response.argument.startDate, response.argument.title);
            data.requestId = YAHOO.util.Dom.generateId();
            // save in cache
            _DATA_CACHE.save([response.argument.type, response.argument.id, data.startDate], data);
                
            this.onGetDataSuccess.fire(data);
        }
        else {
            this.onGetDataFailure.fire(response.argument);
        }
    };
    
    ForecastDataManager.prototype._getDataFailure = function(response) {
        this.onGetDataFailure.fire(response.argument);
    };
    
            
     /**
     * private static method expanding spectral data that comes from webservice
     *
     * @param string
     *
     * @return string
     */
    var _expandCollapsedSpectralData = ForecastDataManager.expandCollapsedSpectralData = function(collapsed) {
        if (collapsed === null) return null;
        return collapsed.replace(/_(\d+)_/g, function (match,num){ return Array(parseInt(num)+1).join("|"); });
    };
    
    /**
     * private static method that fixes single gaps in data
     *
     * @param string
     * @param bool  (opt) if it should round
     *
     * @return string
     */
    var _fixDataGaps = function(data, round) {
        if (data === null) return null;
        return data.replace(/([\d\.]+)\|\|([\d\.]+)/g, 
            function (allmatch, match1, match2){ 
                var m1 = parseFloat(match1);
                var m2 = parseFloat(match2);
                var val = (m1+m2)/2;
                if (round) val = Math.round(val);
                return match1 + "|" + val + "|" + match2; 
            }
        );
    };
    
})();

