using InABox.Core;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using InABox.WPF;
using Color = System.Drawing.Color;
using Image = System.Windows.Controls.Image;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Microsoft.Win32;
using System.Drawing.Imaging;
namespace InABox.DynamicGrid
{
public static class EmbeddedImageUtilities
{
private static BitmapImage? EmptyImage;
private static BitmapImage? EmptySignature;
public static ImageSource CreateEmptyImage()
{
EmptyImage ??= new Bitmap(256, 256).WatermarkImage("No Image", Color.Gray).AsBitmapImage();
return EmptyImage;
}
public static ImageSource CreateEmptySignature()
{
EmptySignature ??= new Bitmap(400, 400).WatermarkImage("No Signature", Color.Gray).AsBitmapImage();
return EmptySignature;
}
public static bool SelectImageFile([NotNullWhen(true)] out byte[]? data)
{
var dlg = new OpenFileDialog();
dlg.Filter = "Image Files (*.jpg;*.png;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp";
if (dlg.ShowDialog() == true)
{
var filename = Path.GetFileName(dlg.FileName).ToLower();
var timestamp = new FileInfo(dlg.FileName).LastWriteTime;
data = File.ReadAllBytes(dlg.FileName);
return true;
}
data = null;
return false;
}
public static byte[]? SaveImageToBytes(Image? image, bool isEmpty, BitmapEncoder encoder)
{
if (image == null
|| image.Source is not BitmapImage bmpimg) return null;
if (isEmpty) return null;
byte[] data;
encoder.Frames.Add(BitmapFrame.Create(bmpimg));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
ms.Seek(0, SeekOrigin.Begin);
data = ms.ToArray();
}
return data;
}
public static string SaveImageToString(Image? image, bool isEmpty, BitmapEncoder encoder)
{
var data = SaveImageToBytes(image, isEmpty, encoder);
return data != null ? Convert.ToBase64String(data) : "";
}
///
/// Loads a value into an Image object.
///
///
///
///
/// if the image is empty.
public static bool LoadImageFromData(Image? image, object? value, Func? defImage = null)
{
if (image == null) return false;
BitmapImage? source = null;
try
{
if (value is string str)
{
source = ImageUtils.BitmapImageFromBase64(str);
}
else if (value is byte[] data)
{
source = ImageUtils.BitmapImageFromBytes(data);
}
}
catch (Exception e)
{
Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
}
if (source != null)
{
image.Source = source;
return true;
}
else
{
image.Source = defImage?.Invoke() ?? CreateEmptyImage();
return false;
}
}
}
public class DFEmbeddedImageControl : DynamicFormFieldControl
{
private Grid Grid = null!; // Late-initialised
private Image Image = null!; // Late-initialised
private bool _isEmpty = true;
protected override FrameworkElement Create()
{
Grid = new Grid();
Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
Image = new Image();
Image.StretchDirection = StretchDirection.DownOnly;
Image.Source = EmbeddedImageUtilities.CreateEmptyImage();
var pasteButton = new Button
{
Content = "Paste",
Margin = new Thickness(0, 5, 5, 0),
Width = 60,
Height = 35
};
pasteButton.Click += PasteButton_Click;
var clearButton = new Button
{
Content = "Clear",
Margin = new Thickness(0, 5, 5, 0),
Width = 60,
Height = 35
};
clearButton.Click += EmbeddedImageClear_Click;
var selectButton = new Button
{
Content = "Select",
Margin = new Thickness(0, 5, 0, 0),
Width = 60,
Height = 35
};
selectButton.Click += EmbeddedImageSelect_Click;
Image.SetGridPosition(0, 0, 1, 4);
pasteButton.SetGridPosition(1, 1, 1, 1);
clearButton.SetGridPosition(1, 2, 1, 1);
selectButton.SetGridPosition(1, 3, 1, 1);
Grid.Children.Add(Image);
Grid.Children.Add(pasteButton);
Grid.Children.Add(clearButton);
Grid.Children.Add(selectButton);
return Grid;
}
private void PasteButton_Click(object sender, RoutedEventArgs e)
{
if (Clipboard.ContainsImage())
{
var paste = Clipboard.GetImage();
var bitmap = ImageUtils.BitmapSourceToBitmap(paste);
var img = ImageUtils.ToBitmapImage(bitmap);
var empty = img == null;
if (_isEmpty != empty)
{
_isEmpty = empty;
if (empty)
Image.Source = EmbeddedImageUtilities.CreateEmptyImage();
else
Image.Source = img;
ChangeField();
}
}
}
public override byte[] GetValue()
{
return EmbeddedImageUtilities.SaveImageToBytes(Image, _isEmpty, new JpegBitmapEncoder()) ?? Array.Empty();
}
public override void SetValue(byte[]? value)
{
_isEmpty = !EmbeddedImageUtilities.LoadImageFromData(Image, value);
}
private void EmbeddedImageClear_Click(object sender, RoutedEventArgs e)
{
if (!_isEmpty)
{
Image.Source = EmbeddedImageUtilities.CreateEmptyImage();
_isEmpty = true;
ChangeField();
}
}
private void EmbeddedImageSelect_Click(object sender, RoutedEventArgs e)
{
if (EmbeddedImageUtilities.SelectImageFile(out var data))
{
var img = ImageUtils.BitmapImageFromBytes(data);
var empty = img == null;
if (_isEmpty != empty)
{
_isEmpty = empty;
if (empty)
Image.Source = EmbeddedImageUtilities.CreateEmptyImage();
else
Image.Source = img;
ChangeField();
}
}
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == IsEnabledProperty)
{
Grid.RowDefinitions[1].Height = (bool)e.NewValue
? GridLength.Auto
: new GridLength(0);
}
}
protected override bool IsEmpty() => _isEmpty;
}
}