using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using C1.Silverlight.Chart;

namespace C1.Silverlight.Chart.Extended
{
  internal static class RenderChart
  {
    /// <summary>
    /// Renders specified chart to bitmap.
    /// </summary>
    /// <param name="chart">Chart</param>
    /// <param name="sz">Size of bitmap.</param>
    /// <param name="rotate">Rotates the chart</param>
    /// <returns>The bitmap with chart.</returns>
    public static WriteableBitmap RenderChartToBitmap(C1Chart chart, Size sz, bool rotate)
    {
      if (rotate)
      {
        var w = sz.Width;
        sz.Width = sz.Height;
        sz.Height = w;
      }

      chart.Width = sz.Width; chart.Height = sz.Height;

      var cont = chart.FindVisualChildByName<ContentPresenter>("viewContent");
      cont.Width = chart.Width; cont.Height = chart.Height;
      cont.Arrange(new Rect(0, 0, chart.Width, chart.Height));

      chart.Measure(new Size(chart.Width, chart.Height));
      chart.Arrange(new Rect(0, 0, chart.Width, chart.Height));
      chart.UpdateLayout();

      var bm = new WriteableBitmap((int)chart.Width, (int)chart.Height);

      bm.Render(chart, new MatrixTransform());
      bm.Invalidate();

      if (rotate)
      {
        bm = Rotate(bm, 270);
      }

      return bm;
    }

    /// <summary>
    /// Rotates specified bitmap.
    /// </summary>
    /// <param name="bmp">Bitmap</param>
    /// <param name="angle">Angle of rotation.</param>
    /// <returns>The rotated bitmap.</returns>
    public static WriteableBitmap Rotate(this WriteableBitmap bmp, int angle)
    {
      var w = bmp.PixelWidth;
      var h = bmp.PixelHeight;
      var p = bmp.Pixels;
      var i = 0;
      WriteableBitmap result = null;
      angle %= 360;

      if (angle > 0 && angle <= 90)
      {
        result = new WriteableBitmap(h, w);
        var rp = result.Pixels;
        for (var x = 0; x < w; x++)
        {
          for (var y = h - 1; y >= 0; y--)
          {
            var srcInd = y * w + x;
            rp[i] = p[srcInd];
            i++;
          }
        }
      }
      else if (angle > 90 && angle <= 180)
      {
        result = new WriteableBitmap(w, h);
        var rp = result.Pixels;
        for (var y = h - 1; y >= 0; y--)
        {
          for (var x = w - 1; x >= 0; x--)
          {
            var srcInd = y * w + x;
            rp[i] = p[srcInd];
            i++;
          }
        }
      }
      else if (angle > 180 && angle <= 270)
      {
        result = new WriteableBitmap(h, w);
        var rp = result.Pixels;
        for (var x = w - 1; x >= 0; x--)
        {
          for (var y = 0; y < h; y++)
          {
            var srcInd = y * w + x;
            rp[i] = p[srcInd];
            i++;
          }
        }
      }
      return result;
    }
  }
}
