using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Maps.MapControl.Core;
using WebSamples.TileRendererEngine.Helpers;
using WebSamples.Utilities.Geo;
using Microsoft.Maps.MapControl;
using WebSamples.Services;
using WebSamples.Entities;
using WebSamples.Entities.Interfaces;

namespace WebSamples.Handlers
{
    /// <summary>
    /// Summary description for TileEngine
    /// </summary>
    public class TileRendererHandler : IHttpHandler
    {
        #region Constants

        const string c_ParamQuadKey = "quadkey";

        #endregion
        
        #region Private fields

        EngineHelper engineHelper = null;
        GeoCityService cityService = new GeoCityService();


        #endregion

        public void ProcessRequest(HttpContext context)
        {
            // Get the parameters
            string quadKeyString = HandlerParameter<string>(context, c_ParamQuadKey, "0");

            // Inititliaze the quadkey
            this.engineHelper = new EngineHelper(new QuadKey(quadKeyString));

            // Get the bounded data from the quadKey
            LocationRect rect = SpatialTools.QuadKeyToLocationRect(new QuadKey(quadKeyString));

            // Get the corresponding data
            IList<IGeoCity> cities =  this.cityService.GetCitiesBounded(rect.Northwest.Latitude, rect.Northwest.Longitude,
                                                                      rect.Southeast.Latitude, rect.Southeast.Longitude);

            // Initialize the image and tile engine helper
            Byte[] pngBuffer = this.engineHelper.GetDefaultTile(cities.Select(c => 
                new GeoPoint() { 
                    Latitude = c.Latitude, 
                    Longitude = c.Longitude 
                }
            ).ToList());


            if (pngBuffer != null)
            {
                context.Response.BufferOutput = true;
                context.Response.Clear();
                context.Response.ClearHeaders();
                context.Response.ContentType = "image/png";
                context.Response.Expires = 0;
                context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                context.Response.Cache.SetNoServerCaching();
                context.Response.Cache.SetNoStore();
                context.Response.Cache.SetMaxAge(System.TimeSpan.Zero);

                context.Response.OutputStream.Write(pngBuffer, 0, pngBuffer.Length);
            }
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }


        // Utilities
        public T HandlerParameter<T>(HttpContext context, string parameterName, T defaultValue)
        {
            T value = defaultValue;

            if (context.Request[parameterName] != null)
            {
                try
                {
                    value = (T)Convert.ChangeType(context.Request[parameterName], defaultValue.GetType());
                }
                catch { }
            }

            return value;

        }

    }
}