using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Pbm;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Tga;
using SixLabors.ImageSharp.Formats.Tiff;
using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.Processing;

using ImageProvider.Extensions;

namespace ImageProvider {
  public class ImageBuilder : IDisposable {

    private Image _image;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="bytes"></param>
    public ImageBuilder(byte[] bytes) {
      _image = Image.Load(bytes);
    }

    public void Load(byte[] bytes) {
      _image = Image.Load(bytes);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="font"> for scaling water mark size is largely ignored.</param>
    /// <param name="text"></param>
    public void Watermark(Font font, string text) =>
      _image = _image.Clone(ctx => ctx.ApplyScalingWaterMark(font, text, Color.HotPink, 5, false));

    /// <summary>
    /// 
    /// </summary>
    /// <param name="font"> for scaling water mark size is largely ignored.</param>
    /// <param name="longText"></param>
    public void WatermarkWordWrap(Font font, string longText) =>
      _image = _image.Clone(ctx => ctx.ApplyScalingWaterMark(font, longText, Color.HotPink, 5, true));

    /// <summary>
    /// 
    /// </summary>
    /// <param name="width"></param>
    /// <param name="height"></param>
    public void Resize(int width, int height) =>
      _image.Mutate(img => img.Resize(width, height));

    public void FitWidthResize(int width) {
      _image.Mutate(x => x.Resize(new ResizeOptions {
        Size = new Size(width, width),
        Mode = ResizeMode.Max
      }));
    }

    public void FitHeightResize(int height) {
      _image.Mutate(x => x.Resize(new ResizeOptions {
        Size = new Size(height, height),
        Mode = ResizeMode.Max
      }));
    }

    public void Crop(int cWidth, int cHeigth) =>
      Crop((_image.Width - cWidth) / 2, (_image.Height - cHeigth) / 2, cWidth, cHeigth);

    public void Crop(int x, int y, int cWidth, int cHeigth) =>
      _image.Mutate(img => img.Crop(new Rectangle(x, y, cWidth, cHeigth)));



    private byte[] Buid(IImageEncoder encoder) {
      using var ms = new MemoryStream();
      _image.Save(ms, encoder);

      return ms.ToArray();
    }

    public byte[] ToGif() => Buid(new GifEncoder());

    public byte[] ToJpeg() => Buid(new JpegEncoder());

    public byte[] ToPbm() => Buid(new PbmEncoder());

    public byte[] ToPng() => Buid(new PngEncoder());

    public byte[] ToTga() => Buid(new TgaEncoder());

    public byte[] ToTiff() => Buid(new TiffEncoder());

    public byte[] ToWebp() => Buid(new WebpEncoder());

    public void Dispose() => _image.Dispose();
  }
}