using Comal.Classes; using InABox.Clients; using InABox.Core; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Xamarin.Forms; using Xamarin.Forms.Xaml; using XF.Material.Forms.UI.Dialogs; namespace comal.timesheets { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class MultiSignaturePad : ContentPage { public MultiSignatureSavedEvent OnMultiSignatureSaved; string Result = ""; List originalnames = new List(); List newnames = new List(); List tempCacheNames = new List(); List addedNames = new List(); double currentheight = 0; Dictionary namesSignatures = new Dictionary(); Dictionary originalNamesSignatures = new Dictionary(); public MultiSignaturePad(string incomingData = "") { InitializeComponent(); AddNames(incomingData); AddPads(3); } void PopulateNames_Clicked(object sender, EventArgs e) { EmployeeSelect list = new EmployeeSelect(true); list.OnEmployeesSaved += List_OnEmployeesSaved; Navigation.PushAsync(list); } private async void List_OnEmployeesSaved(List employees) { using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading")) { foreach (string s in addedNames) { var emp = employees.Find(x => x.Name == s); if (emp != null) employees.Remove(emp); } if (stackLayout.Children.Count < 4) { int extraSignaturesNeeded = 0; if (employees.Count > 3) extraSignaturesNeeded = employees.Count - 3; AddPads(extraSignaturesNeeded); } else AddPads(employees.Count); int count = 0; foreach (SignaturePad pad in stackLayout.Children) { if (string.IsNullOrWhiteSpace(pad.Name)) { try { pad.PopulateName(employees[count].Name); LookupSignature(employees[count].ID, pad); addedNames.Add(employees[count].Name); count++; } catch { } } } } } private void LookupSignature(Guid employeeID, SignaturePad pad) { try { CoreTable table = new Client().Query(new Filter(x => x.ID).IsEqualTo(employeeID), new Columns(x => x.Signature)); if (table.Rows.Any()) { byte[] data = table.Rows.First().Get("Signature"); if (data != null) pad.PopulateSignature(data); } } catch { } } void AddNames(string incomingData) { if (!string.IsNullOrWhiteSpace(incomingData)) { try { Dictionary incoming = Serialization.Deserialize>(incomingData); originalNamesSignatures = Serialization.Deserialize>(incomingData); foreach (string s in incoming.Keys) { originalnames.Add(s); } if (originalnames.Count > 0) { int index = fixedStackLayout.Children.Count - 1; ScrollView scrollView = new ScrollView { Orientation = ScrollOrientation.Horizontal, HeightRequest = 50 }; StackLayout newStackLayout = new StackLayout { Orientation = StackOrientation.Horizontal }; scrollView.Content = newStackLayout; fixedStackLayout.Children.Insert (index, new Label { Text = "Previously signed: ", HorizontalOptions = LayoutOptions.Center, FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.Center, FontSize = 20 } ); fixedStackLayout.Children.Insert ( index + 1, scrollView ); int count = 1; foreach (string s in originalnames) { newStackLayout.Children.Add ( new Frame { BorderColor = Color.FromHex("#873260"), CornerRadius = 5, HasShadow = false, Padding = 0, Content = new Label { Text = count + ". " + s, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center, FontSize = 16, Margin = new Thickness(6, 0, 6, 0) } } ); count++; } } } catch { } } } void AddPads(int count) { for (int i = 0; i < count; i++) { AddPad(); } } void AddPad() { SignaturePad pad = new SignaturePad(); pad.HeightRequest = 200; pad.Margin = new Thickness(1); pad.OnNameAdded += (s) => { if (tempCacheNames.Contains(s) || originalnames.Contains(s)) { DisplayAlert("Error", "Duplicate name detected for " + s + ". Please try again", "OK"); pad.ClearName(); } else tempCacheNames.Add(s); }; pad.OnNameRemoved += (s) => { if (tempCacheNames.Contains(s)) tempCacheNames.Remove(s); if (addedNames.Contains(s)) addedNames.Remove(s); }; stackLayout.Children.Add(pad); } void Scrolldown_Tapped(object sender, EventArgs e) { AddPad(); double height = 600; foreach (SignaturePad signaturePad in stackLayout.Children) { height = height + 200; } currentheight = height; scrollView.ScrollToAsync(0, height, true); } void AddSignature_Clicked(object sender, EventArgs e) { AddPad(); double height = 600; foreach (SignaturePad signaturePad in stackLayout.Children) { height = height + 200; } currentheight = height; scrollView.ScrollToAsync(0, height, true); } void Save_Clicked(object sender, EventArgs e) { namesSignatures.Clear(); newnames.Clear(); foreach (SignaturePad pad in stackLayout.Children) { if (!string.IsNullOrWhiteSpace(pad.Name)) { if (originalnames.Contains(pad.Name)) { DisplayAlert("Error", "Duplicate names entered for " + pad.Name + " - please check and try again", "OK"); return; } if (newnames.Contains(pad.Name)) { DisplayAlert("Error", "Duplicate names entered for " + pad.Name + " - please check and try again", "OK"); return; } else newnames.Add(pad.Name); } } foreach (SignaturePad pad in stackLayout.Children) { if (pad.StrokeAdded) { if (string.IsNullOrWhiteSpace(pad.Name)) { DisplayAlert("Error", "Please fill in a name for all pads that have signatures", "OK"); return; } } if (!string.IsNullOrWhiteSpace(pad.Name)) { if (!pad.StrokeAdded) { DisplayAlert("Error", "Please add a signature for all names", "OK"); return; } } } foreach (SignaturePad pad in stackLayout.Children) { if (!string.IsNullOrWhiteSpace(pad.Name)) { pad.SaveSignature(); //saves image to base64 if (!string.IsNullOrWhiteSpace(pad.Data)) if (!namesSignatures.ContainsKey(pad.Name) && !originalNamesSignatures.ContainsKey(pad.Name)) namesSignatures.Add(pad.Name, pad.Data); } } if (namesSignatures.Count > 0) { if (originalNamesSignatures.Count > 0) { foreach (var v in namesSignatures) { originalNamesSignatures.Add(v.Key, v.Value); } Result = Serialization.Serialize(originalNamesSignatures); } else { Result = Serialization.Serialize(namesSignatures); } OnMultiSignatureSaved?.Invoke(Result); DisplayAlert("Success", namesSignatures.Count + " signatures added to form. Form still needs to be saved", "OK"); } Navigation.PopAsync(); } } public delegate void MultiSignatureSavedEvent(string result); }