using InABox.Core;
using System;
using System.Drawing;
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 System.Linq;
using Microsoft.Win32;
using Syncfusion.UI.Xaml.ImageEditor;
using InABox.Wpf;
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 Border? _border;
private Image _image = null!; // Late-initialised
private bool _isEmpty = true;
private Button viewButton = null!;
private Button pasteButton = null!;
private Button clearButton = null!;
private Button selectButton = null!;
private DFLayoutEmbeddedMediaValue _value = null!;
static DFEmbeddedImageControl()
{
IsEnabledProperty.OverrideMetadata(
typeof(DFEmbeddedImageControl),
new UIPropertyMetadata(
true,
ControlIsEnabledChanged));
}
private static void ControlIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var control = (DFEmbeddedImageControl)obj;
control.IsEnabled = true;
var enabled = (bool)e.NewValue;
control.pasteButton.Visibility = enabled ? Visibility.Visible : Visibility.Collapsed;
control.clearButton.Visibility = enabled ? Visibility.Visible : Visibility.Collapsed;
control.selectButton.Visibility = enabled ? Visibility.Visible : Visibility.Collapsed;
}
protected override FrameworkElement Create()
{
_value = new DFLayoutEmbeddedMediaValue();
_grid = new Grid();
_grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
_grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
_grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
_grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
_grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
_grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
_border = new Border()
{
BorderBrush = new SolidColorBrush(Colors.Gray),
BorderThickness = new Thickness(0.75),
Background = new SolidColorBrush(Colors.White),
Padding = new Thickness(4),
Margin = new Thickness(0)
};
_border.SetGridPosition(0,0,5,1);
_grid.Children.Add(_border);
_image = new Image
{
Stretch = Stretch.Uniform,
//StretchDirection = StretchDirection.DownOnly,
Source = EmbeddedImageUtilities.CreateEmptyImage(),
};
_border.Child = _image;
viewButton = new Button
{
Content = Content = new Image { Source = Wpf.Resources.zoomin.AsBitmapImage(24, 24), Margin = new Thickness(2) },
Margin = new Thickness(5, 0, 0, 0),
Width = 30,
Height = 30
};
viewButton.Click += ViewButton_Click;
viewButton.SetGridPosition(0,1);
_grid.Children.Add(viewButton);
pasteButton = new Button
{
Content = Content = new Image { Source = Wpf.Resources.paste.AsBitmapImage(24, 24) },
Margin = new Thickness(5, 5, 0, 0),
Width = 30,
Height = 30
};
pasteButton.Click += PasteButton_Click;
pasteButton.SetGridPosition(2, 1);
_grid.Children.Add(pasteButton);
clearButton = new Button
{
Content = Content = new Image { Source = Wpf.Resources.delete.AsBitmapImage(24, 24) },
Margin = new Thickness(5, 5, 0, 0),
Width = 30,
Height = 30
};
clearButton.Click += EmbeddedImageClear_Click;
clearButton.SetGridPosition(3,1);
_grid.Children.Add(clearButton);
selectButton = new Button
{
Content = Content = new Image { Source = Wpf.Resources.load.AsBitmapImage(24, 24) },
Margin = new Thickness(5, 5, 0, 0),
Width = 30,
Height = 30
};
selectButton.Click += EmbeddedImageSelect_Click;
selectButton.SetGridPosition(4, 1);
_grid.Children.Add(selectButton);
return _grid;
}
private static void ShowImage(byte[] data)
{
var src = ImageUtils.LoadImage(data);
var editor = new SfImageEditor
{
ImageSource = src
};
var window = new Window() { Content = editor, Height = 800, Width=800 };
window.ShowDialog();
}
private void ViewButton_Click(object sender, RoutedEventArgs e)
{
if (_value.Data?.Any() == true)
ShowImage(_value.Data);
else
{
DigitalFormDocumentFactory.LoadDocument(_value.ID, (data) =>
{
if(data.Length == 0)
{
Dispatcher.BeginInvoke(() =>
MessageWindow.ShowMessage("The image should be in the database, but it is not.", "Document not found", image: MessageWindow.WarningImage));
}
else
{
_value.Data = data;
Dispatcher.BeginInvoke(() => ShowImage(data));
}
});
}
}
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;
SetSerializedValue(new DFLayoutEmbeddedMediaValue
{
Data = EmbeddedImageUtilities.SaveImageToBytes(_image, _isEmpty, new JpegBitmapEncoder()) ?? Array.Empty()
});
ChangeField();
}
}
}
public override void SetSerializedValue(DFLayoutEmbeddedMediaValue value)
{
_value = value;
_value.Thumbnail ??= _value.Data != null
? ImageUtils.BitmapImageFromBytes(_value.Data)?.Resize(200, 200).ToArray()
: null;
_isEmpty = !EmbeddedImageUtilities.LoadImageFromData(_image, _value.Data?.Any() == true ? _value.Data : _value.Thumbnail);
}
public override DFLayoutEmbeddedMediaValue GetSerializedValue()
{
if ((_value.Data?.Any() == true) && (_value.ID == Guid.Empty))
_value.ID = DigitalFormDocumentFactory.SaveDocument(_value.Data);
return _value;
}
public override Guid GetValue()
{
return _value.ID;
}
public override void SetValue(Guid value)
{
SetSerializedValue(new DFLayoutEmbeddedMediaValue() { ID = value });
}
private void EmbeddedImageClear_Click(object sender, RoutedEventArgs e)
{
if (!_isEmpty)
{
_image.Source = EmbeddedImageUtilities.CreateEmptyImage();
_isEmpty = true;
SetSerializedValue(new DFLayoutEmbeddedMediaValue());
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;
SetSerializedValue(new DFLayoutEmbeddedMediaValue
{
Data = data
});
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;
}
}