using System; using System.IO; using System.Linq; using System.Threading.Tasks; using InABox.Core; using InABox.Mobile; using Xamarin.Forms; namespace PRS.Mobile { public abstract class DigitalFormEmbeddedMedia : Grid, IDigitalFormField where T : DFLayoutField, new() where TProperties : DFLayoutFieldProperties, new() { protected abstract bool IsVideo { get; } private readonly MobileCard _card; private readonly Image _image; private readonly MobileButton _cameraButton; private readonly MobileButton _libraryButton; private T? _definition; public T? Definition { get => _definition; set { _definition = value; Initialize(value ?? new T()); } } protected DFLayoutEmbeddedMediaValue _value = new(); protected abstract TValue GetValue(); protected abstract void SetValue(TValue value); public TValue Value { get => GetValue(); set { SetValue(value); UpdateUI(); } } protected void AddButton(ImageSource image, Action action) { RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); _card.SetValue(Grid.RowSpanProperty, RowDefinitions.Count); var _button = new MobileButton { Image = image, ImageSize = new Size(25, 25), Orientation = StackOrientation.Vertical, CornerRadius = 5, WidthRequest = 40, HeightRequest = 40, }; SetColumn(_button, 1); SetRow(_button, RowDefinitions.Count-1); _button.Clicked += (sender, args) => action(); Children.Add(_button); } protected abstract byte[] CreateThumbnail(byte[] data, int maxwidth = 256, int maxheight = 256); protected void UpdateUI() { if ((_value.Thumbnail?.Any() != true) && (_value.Data?.Any() == true)) _value.Thumbnail = CreateThumbnail(_value.Data); _image.Source = _value.Thumbnail?.Any() == true ? ImageSource.FromStream(() => new MemoryStream(_value.Thumbnail)) : null; } public bool IsEmpty => _value.Data?.Any() != true; private bool _readOnly; public bool ReadOnly { get => _readOnly; set { _readOnly = value; UpdateStatus(); } } public void Deserialize(DFLoadStorageEntry entry) { _value = Definition?.Properties.DeserializeValue(entry) ?? new DFLayoutEmbeddedMediaValue(); UpdateUI(); } public void Serialize(DFSaveStorageEntry entry) { if ((_value.Data?.Any() == true) && (_value.ID == Guid.Empty)) _value.ID = DigitalFormDocumentFactory.SaveDocument(_value.Data); Definition?.Properties.SerializeValue(entry, _value); } public event DigitalFormViewChangedHandler? ValueChanged; protected DigitalFormEmbeddedMedia() { HeightRequest = 250; ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); _card = new MobileCard() { Padding = 5, IsClickable = true, }; _card.Clicked += ((o,e) => Image_Tapped()); SetRow(_card, 0); SetColumn(_card, 0); SetRowSpan(_card, 4); Children.Add(_card); _image = new Image() { Aspect = Aspect.AspectFit }; _image.GestureRecognizers.Add(new TapGestureRecognizer() { Command = new Command(Image_Tapped) }); _card.Content = _image; _cameraButton = new MobileButton { Image = "camera", ImageSize = new Size(25, 25), Orientation = StackOrientation.Vertical, CornerRadius = 5, WidthRequest = 40, HeightRequest = 40, }; SetRow(_cameraButton, 0); SetColumn(_cameraButton, 1); _cameraButton.Clicked += CameraButton_Clicked; Children.Add(_cameraButton); _libraryButton = new MobileButton { Image = "gallery", ImageSize = new Size(25, 25), Orientation = StackOrientation.Vertical, CornerRadius = 5, WidthRequest = 40, HeightRequest = 40, }; SetRow(_libraryButton, 1); SetColumn(_libraryButton, 1); _libraryButton.Clicked += LibraryButton_Clicked; Children.Add(_libraryButton); } private void Image_Tapped() { if (_value.Thumbnail?.Any() == false) return; if (_value.Data?.Any() == true) Navigation.PushAsync( new ImageViewerPage( _value.Data, () => { _value.ID = Guid.Empty; _value.Thumbnail = null; _value.Data = null; UpdateUI(); } ) ); else { if (_value.ID != Guid.Empty) { DigitalFormDocumentFactory.LoadDocument( _value.ID, data => { Device.BeginInvokeOnMainThread(() => { _value.Data = data; Navigation.PushAsync( new ImageViewerPage( _value.Data, () => { _value.ID = Guid.Empty; _value.Thumbnail = null; _value.Data = null; UpdateUI(); } ) ); }); } ); } } } protected abstract Task CaptureMedia(); protected abstract Task SelectMedia(); private async void CameraButton_Clicked(object sender, MobileButtonClickEventArgs args) { // MobileDocumentForm.Show( // Navigation, // new MobileDocumentCameraOptions(), // (doc) => // { // _value.ID = Guid.Empty; // _value.Thumbnail = CreateThumbnail(doc.Data); // _value.Data = doc.Data; // Device.BeginInvokeOnMainThread(UpdateUI); // } // ); var doc = await CaptureMedia(); if (doc.Data?.Any() == true) { _value.ID = Guid.Empty; _value.Thumbnail = CreateThumbnail(doc.Data); _value.Data = doc.Data; } Device.BeginInvokeOnMainThread(UpdateUI); } private async void LibraryButton_Clicked(object sender, MobileButtonClickEventArgs args) { // MobileDocumentForm.Show( // Navigation, // new MobileDocumentPhotoLibraryOptions(), // (doc) => // { // _value.ID = Guid.Empty; // _value.Thumbnail = CreateThumbnail(doc.Data); // _value.Data = doc.Data; // Device.BeginInvokeOnMainThread(UpdateUI); // } // ); var doc = await SelectMedia(); if (doc.Data?.Any() == true) { _value.ID = Guid.Empty; _value.Thumbnail = CreateThumbnail(doc.Data); _value.Data = doc.Data; } Device.BeginInvokeOnMainThread(UpdateUI); } private void RotateButton_Clicked(object sender, MobileButtonClickEventArgs args) { } private void Initialize(T definition) { UpdateStatus(); } protected abstract bool DisableLibrary { get; } protected abstract bool Secure { get; } protected abstract bool Required { get; } private void UpdateStatus() { _cameraButton.Image = IsVideo ? ImageSource.FromFile("camcorder") : ImageSource.FromFile("camera"); _libraryButton.Image = IsVideo ? ImageSource.FromFile("videolibrary") : ImageSource.FromFile("photolibrary"); _libraryButton.IsEnabled = !DisableLibrary; bool enabled = !_readOnly && !Secure; _cameraButton.IsEnabled = enabled; _libraryButton.IsEnabled = enabled && !DisableLibrary; var colors = DigitalFormUtils.GetColors(!enabled, Required, false); _card.BackgroundColor = colors.Background; _card.BorderColor = colors.Border; colors = DigitalFormUtils.GetColors(!enabled, Required, true); _cameraButton.BackgroundColor = colors.Background; _cameraButton.BorderColor = colors.Border; _libraryButton.BackgroundColor = colors.Background; _libraryButton.BorderColor = colors.Border; } } }