function WeatherWidget(element)
{
    this.init(element);
}

WeatherWidget.prototype =
{
    element: null,
    uri: 'weather.php?q=%s',
    
    // e.g. Tuesday 11 January, 2010
    dateFormat: 'dddd d mmmm, yyyy',
    
    init: function(element)
    {
        this.element = element;
        var self = this;
        
        // Insert today's date into the field
        $(this.element).find('#Today').text(this.getToday());
        
        // Now bless the element's form
        $(this.element).find('form').submit(function()
        {
            // Make the function returns false so that the 
            // page won't reload
            try
            {
                self.query($(self.element).find(':input').val());
            }
            finally
            {
                return false;
            }
        });
        
        $(this.element).find('.placePostalCode').click(function()
        {
            self.query($(this).text());
        });
    },
    
    getToday: function()
    {
    	return (new Date()).format(this.dateFormat);
    },
    
    startLoading: function()
    {
    	this._hideAllPages();
        $(this.element).find('.search :submit').disable().val("Loading...");
    },
    
    stopLoading: function()
    {
        $(this.element).find('.search :submit').enable().val("Search");
    },
    
    setTitle: function(title)
    {
        $(this.element).find('h3').text(title);
    },
    
    _hideAllPages: function()
    {
    	$(this.elemnet).find('.widgetPage').hide();
    },
    
    _showPage: function(element)
    {
    	this._hideAllPages();
        $(element).show();
    },
    
    showForecasts: function(forecasts)
    {
        console.log("Forecast received", forecasts);
        
        var element = $(this.element).find('#WeatherForecasts');
        this._showPage(element);
        this.setTitle(forecasts.place);
        
        /*
         * Show the meta stuffs
         */
        $(this.element).find('.tempUnit').text(forecasts.tempUnit);
        
        /*
         * Show the current condition
         */
        var c = forecasts.current;
        if(c)
        {
	        var target = $(this.element).find('.current.forecast');
	            console.log("Injecting into target", target);
	        $(target).find('.temp').text(c.temp);
	        $(target).find('.condition').text(c.condition);
	        $(target).find('.icon img')
	        	.attr('src', c.iconUrl).attr('alt', c.condition);
        }
        
        /*
         * Show the forecasts
         * The first forecast is today's forecast
         */
        for(var i in forecasts.forecasts)
        {
            var f = forecasts.forecasts[i];
            
            var selector = sprintf(".forecast:not('.current'):eq(%s)", i);
            var target = $(this.element).find(selector);
            
            console.log("Injecting into selector", selector);
            
            $(target).find('.dayOfWeek').text(f.dayOfWeek);
            $(target).find('.low').text(f.low);
            $(target).find('.high').text(f.high);
            $(target).find('.condition').text(f.condition);
            $(target).find('.icon img')
            	.attr('src', f.iconUrl)
            	.attr('alt', f.condition);
        }
    },
    
    showError: function(message)
    {
        var element = $(this.element).find('#WeatherMessage');
        this._showPage(element);
        $(element).text(message);
        this.setTitle("");
    },
    
    showClosest: function(places)
    {
        var element = $(this.element).find('#WeatherClosestPlaces');
        this._showPage(element);
        this.setTitle("Please try instead...");
        
        for(var i in places)
        {
            var p = places[i];
            var selector = sprintf(".place:eq(%s)", i);
            var target = $(this.element).find(selector);
            
            $(target).find('.placeName').text(p.name);
            $(target).find('.placePostalCode').text(p.postalCode);
        }
    },
    
    query: function(query)
    {
        var uri = sprintf(this.uri, query);
        var self = this;
        
        $(this.element).find(':input').val(query);
        
        this.startLoading();
        
        var options = 
        {
            url: uri,
            cache: false,
            dataType: 'json',
            success: function(response)
	        {
	            self.stopLoading();
	            switch(response.type)
	            {
		            case 'ok':
		                self.showForecasts(response.forecasts);
	                break;
	                
		            case 'closest':
		                self.showClosest(response.closestPlaces);
	                break;
	                
	                default:
	                case 'error':
	                    if(response.errorMessage) self.showError(response.errorMessage);
	                    else self.showError("Unspecified error occurred");
	                break;
	            }
	        },
	        
	        complete: function()
	        {
	            self.stopLoading();
	        },
	        
	        error: function()
	        {
	            self.showError("Server side error");
	        }
        };
        
        $.ajax(options);
    }
};
