using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Microsoft.Maps.MapControl.Core;
using System.Drawing.Imaging;
using System.IO;
using WebSamples.Utilities.Geo;
using WebSamples.Entities;
using Microsoft.Maps.MapControl;
using WebSamples.Entities.Interfaces;

namespace WebSamples.TileRendererEngine
{
    // Inspired from a good sample by Ricky Brunditt
    // http://rbrundritt.spaces.live.com/blog/cns!E7DBA9A4BFD458C5!1047.entry
    public class TileRenderer
    {
        #region Constants

        const int c_ElipseDefaultSize = 8;

        #endregion

        #region Private fields

        QuadKey quadKey;
        Bitmap bitmap = null;
        PointF topLeftPixel;

        #endregion

        #region Constructors

        public TileRenderer(QuadKey quadKey)
        {
            this.quadKey = quadKey;

            this.topLeftPixel = new PointF();
            this.topLeftPixel.X = quadKey.X * 256;
            this.topLeftPixel.Y = quadKey.Y * 256;

            this.bitmap = new Bitmap(256, 256, PixelFormat.Format32bppArgb);
            this.bitmap.SetResolution(256, 256);

            Graphics gr = Graphics.FromImage(this.bitmap);
            gr.FillRectangle(new SolidBrush(Color.Transparent), new Rectangle(0, 0, 256, 256));
            gr.Dispose();
        }

        public void RenderTileFromData(List<GeoPoint> shapes)
        {
            //define the map as a gaphics object
            Graphics gr = Graphics.FromImage(this.bitmap);
            //gr.SmoothingMode = SmoothingMode.AntiAlias;

            double zoomMapWidth = SpatialTools.ZoomMapWidth(this.quadKey.ZoomLevel);

            for (int i = 0; i < shapes.Count; i++)
            {
                // Support only point
                PointF curPoint = SpatialTools.CoordinateToPointF(
                    new Location(shapes[i].Latitude, shapes[i].Longitude),
                    (int)zoomMapWidth,
                    this.quadKey.ZoomLevel
                );

                gr.FillEllipse(new SolidBrush(Color.DarkCyan),
                               curPoint.X - (c_ElipseDefaultSize / 2),
                               curPoint.Y - (c_ElipseDefaultSize / 2),
                               c_ElipseDefaultSize, c_ElipseDefaultSize);
            }

            gr.Dispose();
        }

        public Byte[] GetPNGByteBuffer()
        {
            MemoryStream stream = new MemoryStream();
            this.bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            return stream.ToArray();
        }

        public void Dispose()
        {
            this.bitmap.Dispose();
        }

        #endregion
    }
}
