general.namespace('SW.Controls');

(function() {
    /**
    * ctor
    */
    var ForecastChart = SW.Controls.ForecastChart = function(chartContainerParent, showSurf, showWind, showTide, showWeather) {
        this.uniqueId = YAHOO.util.Dom.generateId();
        this.currentDataPointId = 0; // holds the id of the vbuoy or region that is currently displayed
        this.currentStartDate = null;
        this.markedDateTime = null;
        this.dataCache = new general.Cache();
        this.firstAttempt = false;

        // initial state of showing the different chart pieces
        if (typeof showSurf == "undefined") this.showSurf = true;
        else this.showSurf = showSurf;
        if (typeof showWind == "undefined") this.showWind = true;
        else this.showWind = showWind;
        if (typeof showTide == "undefined") this.showTide = true;
        else this.showTide = showTide;
        if (typeof showWeather == "undefined") this.showWeather = true;
        else this.showWeather = showWeather;

        this.onHeightChange = new YAHOO.util.CustomEvent("onHeightChange", this, false, YAHOO.util.CustomEvent.FLAT);
        this.onDataDisplayComplete = new YAHOO.util.CustomEvent("onDataDisplayComplete", this, false, YAHOO.util.CustomEvent.FLAT);
        this.render(chartContainerParent);
    };
    ForecastChart.prototype.constructor = ForecastChart;

    /**
    * attaches an iframe, which contains the chart flash, to the container
    *
    * @param object  the DOM element to append the whole shebang to
    *
    * @return void
    */
    ForecastChart.prototype.render = function(chartContainerParent) {
        this.chartContainer = document.createElement("div");
        this.chartContainer.style.position = "relative";

        this.overlay = document.createElement("div");
        this.overlay.className = "chart-overlay";

        this.message = document.createElement("div");
        this.message.className = "chart-message-notice";

        this.iframe = general.createIFrame(this.uniqueId + "_chartContainer", 515, 0, "/dep/forecast-chart.aspx");
        this.weatherContainer = document.createElement("div");
        this.weatherContainer.style.height = "114px";

        // add items to container
        this.chartContainer.appendChild(this.iframe);
        this.chartContainer.appendChild(this.weatherContainer);
        this.chartContainer.appendChild(this.overlay);
        this.chartContainer.appendChild(this.message);
        // add to doc
        chartContainerParent.appendChild(this.chartContainer);

        this.weatherChart = new SW.Controls.WeatherChart(this.weatherContainer);
        this.iframeWindow = general.getFrameWindow(this.iframe);

        // use timeout to avoid race condition in Firefox 1.5
        var me = this;
        window.setTimeout(
            function() {
                // give the window a reference to this chart object
                me.iframeWindow.SW_ForecastChart = me;
            },
            0
        );
    };

    /**
    * updates visible graphs and headings in the chart
    *
    * @param bool  showSurf
    * @param bool  showWind
    * @param bool  showTide
    * @param bool  showWeather
    *
    * @return void
    */
    ForecastChart.prototype.updateChartParts = function(showSurf, showWind, showTide, showWeather) {
        this.showSurf = showSurf;
        this.showWind = showWind;
        this.showTide = showTide;
        this.showWeather = showWeather;
        this.toggleWeatherChart(showWeather);
        var theFlashInstance = this.getFlashInstance();
        theFlashInstance.readjust(showSurf ? "on" : "off", showWind ? "on" : "off", showTide ? "on" : "off", showWeather ? "on" : "off");
    };


    /**
    * shows or hides the weather
    *
    * @param bool  whether or not to show it
    * @param bool  showWind
    * @param bool  showTide
    * @param bool  showWeather
    *
    * @return void
    */
    ForecastChart.prototype.toggleWeatherChart = function(showWeather) {
        this.weatherContainer.style.display = showWeather ? "block" : "none";
    };

    /**
    * sets the visible height of the chart
    *
    * @param string  date and time formatted like "2008-03-02 15:36" in local time to the data
    *
    * @return void
    */
    ForecastChart.prototype.setMarkedDateTime = function(dateTime) {
        this.markedDateTime = dateTime;
    };

    /**
    * sets the visible height of the chart
    *
    * @param int  height in pixels
    *
    * @return void
    */
    ForecastChart.prototype.setHeight = function(height) {
        // the setTimeout is to fix an ie6 reflow bug
        var me = this;
        setTimeout(function() { me.iframe.style.height = height + "px"; }, 0);
        this.onHeightChange.fire(height);
    };

    /**
    * called by flash when the drawing is done
    *
    * @param int  height in pixels
    *
    * @return void
    */
    ForecastChart.prototype.dataDisplayComplete = function(height) {
        // mark specific time
        if (this.markedDateTime) {
            var theFlashInstance = this.getFlashInstance();
            theFlashInstance.setMark(this.markedDateTime);
        }
        // draw the weather now that the flash has been drawn, and see if there is weather data 
        // if there is not data, subtract 40px from the flash iframe to hide the title bar
        var hasWeatherData = this.weatherChart.render();
        if (!hasWeatherData && (height > 40)) {
            height -= 40;
        }
        this.setHeight(height);
        this.hideMessage();
        this.onDataDisplayComplete.fire(height);
    };


    /**
    * gets the visible height of the chart
    *
    * @return int  height in pixels
    */
    ForecastChart.prototype.getHeight = function() {
        var iframeHt = parseInt(this.iframe.style.height);
        if (iframeHt > 0) {
            iframeHt += 114; // height of weather
        }
        return iframeHt;
    };


    /**
    * gets the DOM element of the flash chart object
    *
    * @return object  the DOM element
    */
    ForecastChart.prototype.getFlashInstance = function() {
        try {
            return this.iframeWindow.document.getElementById("flashObjectCharts");
        } catch (ex) {
            general.reportClientError('ForecastChart.prototype.getFlashInstance: seems to be race condition where element doesn\'t always exist by time of getElementById');
        }
    };

    /**
    * show a message
    *
    * @param string  if blank, screen will still be obscured
    * @param bool  if it is an error, default false
    *
    * @return void
    */
    ForecastChart.prototype.displayMessage = function(message, isError) {
        if (this.getHeight() < 200) {
            this.setHeight(200);
        }
        var me = this;
        // this setTimeout fixes a reflow bug in all browsers
        setTimeout(function() {
            me.overlay.style.height = me.getHeight() + "px";
            me.overlay.style.display = "block";
        }, 0);
        var msgObj = this.message;
        setTimeout(function() { msgObj.style.display = "none"; }, 0);
        if (message) {
            setTimeout(
                function() {
                    msgObj.className = (isError ? "chart-message-error" : "chart-message-notice");
                    msgObj.innerHTML = message;
                    msgObj.style.display = "block";
                },
                0
            );
        }
    };

    /**/
    ForecastChart.prototype.displayError = function(message) {
        this.displayMessage(message, true);
    };

    /**
    * hides message
    *
    * @return void
    */
    ForecastChart.prototype.hideMessage = function() {
        this.message.style.display = "none";
        this.overlay.style.display = "none";
    };


    /**
    * method for displaying region data
    *
    * @param object  data to display
    *
    * @return void
    */
    ForecastChart.prototype.displayData = function(data) {
        if (data && data.VirtualBuoyData && data.VirtualBuoyData.Spectral) {
            // flash must be in view before its functions are exposed
            if (this.getHeight() <= 0) this.setHeight(800);
            this.setFlashData(data);
            // set the weather chart data
            // show/hide weather
            this.toggleWeatherChart(this.showWeather);
            this.weatherChart.setWeatherData((data.WeatherForecastData ? data.WeatherForecastData : []));
        }
        else {
            if (this.getHeight() <= 0) this.setHeight(200);
            var msg = "Sorry, there is no data for <br />'" + data.title + "'";
            if (data.startDate) {
                msg += "<br /> on " + general.dateFormat(data.startDate, general.dateFormat.masks.mediumDate);
            }
            this.displayMessage(msg);
            this.onDataDisplayComplete.fire(this.getHeight());
        }
    };



    /**
    * sets the data in the flash object
    *
    * @return void
    */
    ForecastChart.prototype.setFlashData = function(data) {
        var attemptDrawCount = 0;

        if (this.attemptDrawHandle) {
            clearInterval(this.attemptDrawHandle);
            this.attemptDrawHandle = null;
        }

        var me = this;
        // closure for retries
        var attemptDraw = function() {
            var theFlashInstance = me.getFlashInstance();
            if (theFlashInstance && theFlashInstance.setData) {
                setTimeout(
                    function() {
                        theFlashInstance.setData(
                            data.VirtualBuoyData.WaveHeight, // WaveHeightNW
                            null, // WaveHeightNE
                            null, // WaveHeightSE 
                            null, // WaveHeightSW 
                            data.VirtualBuoyData.WaveDirection, // WaveDirectionNW
                            null, // WaveDirectionNE
                            null, // WaveDirectionSE
                            null, // WaveDirectionSW
                            data.VirtualBuoyData.Period, // PeriodNW
                            null, // PeriodNE
                            null, // PeriodSE
                            null, // PeriodSW
                            data.VirtualBuoyData.WindSpeed,
                            data.VirtualBuoyData.WindDirection,
                            data.VirtualBuoyData.Spectral,
                            data.VirtualBuoyData.SpectralEnergySum,
                            data.startDateIsoFormatted, // this comes formatted yyyy-mm-dd 
                            data.DefaultTideStationId,
                            SWMap.userPrefs.uom, // TODO make property instead of global?
                            SWMap.userPrefs.timeFormat, // TODO make property instead of global?
                            data.title,
                            data.TideData,
                            (me.showSurf ? "on" : "off"),
                            (me.showWind ? "on" : "off"),
                            (me.showTide ? "on" : "off"),
                            (me.showWeather ? "on" : "off")
                        );
                    },
                    0
                );
                // save the successful startDate
                me.currentStartDate = data.startDate;
                // save the successful regionid - used for changing date
                me.currentDataPointId = data.dataPointId;

                clearInterval(me.attemptDrawHandle);
                me.attemptDrawHandle = null;
            }
        }; // end of closure
        this.attemptDrawHandle = setInterval(attemptDraw, 250);
    };

    /**
    * static method for writing out flash object
    * depends on deconcept flash object
    *
    * @param object  DOM element to write flash into
    *
    * @return void
    */
    ForecastChart.writeFlash = function(flashContainer) {
        var so = new SWFObject(
            "/assets/flash/surf_chart.swf?r=9",
            "flashObjectCharts",
            "515",
            "2800",
            "8",
            "#FFFFFF"
        );
        so.addParam("wmode", "transparent");
        so.addParam("quality", "high");
        so.write(flashContainer);
    };




})();