/**
         * BARCODE DETECTOR
         */
        async void BarcodeScannerClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            var config = new BarcodeScannerConfiguration();
            //config.BarcodeFormats = BarcodeTypes.Instance.AcceptedTypes;

            var result = await SBSDK.UI.LaunchBarcodeScannerAsync(config);

            if (result.Status == OperationResult.Ok)
            {
                if (result.Barcodes.Count == 0)
                {
                    ViewUtils.Alert(this, "Oops!", "No barcodes found, please try again");
                    return;
                }

                var source   = result.Image;
                var barcodes = result.Barcodes;

                await Navigation.PushAsync(new BarcodeResultsPage(source, barcodes));
            }
        }
        async void WorkflowDCClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            var workflow = SBSDK.UI.CreateWorkflow();
            var ratios   = new[] {
                // DC form A5 portrait (e.g. white sheet, AUB Muster 1b/E (1/2018))
                new AspectRatio(148.0, 210.0),
                // DC form A6 landscape (e.g. yellow sheet, AUB Muster 1b (1.2018))
                new AspectRatio(148.0, 105.0)
            };

            workflow.AddScanDisabilityCertificateStep(
                title: "Scan Disability Certificate",
                message: "Please align the DC form in the frame.",
                requiredAspectRatios: ratios,
                resultValidationHandler: (o, args) =>
            {
                var result = args.Result as IWorkflowDisabilityCertificateResult;
                if (!result.DisabilityCertificate.RecognitionSuccessful)
                {
                    string message = "Could not extract data. Please try again.";
                    args.SetError(message, ValidationErrorShowMode.Alert);
                    return;
                }
                // run some additional validations here
                //result.DisabilityCertificate.Dates....
                //result.DisabilityCertificate.Checkboxes...
            }
                );
            await RunWorkflow(workflow);
        }
        async void WorkflowPayformClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            var workflow = SBSDK.UI.CreateWorkflow();

            workflow.AddScanPayFormStep(
                title: "PayForm Scanner",
                message: "Please scan a SEPA PayForm",
                resultValidationHandler: (o, args) =>
            {
                var result = args.Result as IWorkflowPayFormResult;
                if (result.PayForm == null || result.PayForm.RecognizedFields.Count == 0)
                {
                    args.SetError("Recognition was not successful. " +
                                  "Please try again.", ValidationErrorShowMode.Alert);
                    return;
                }
                // run some additional validations here
                //result.PayForm.RecognizedFields...
            }
                );
            await RunWorkflow(workflow);
        }
        /**
         * DOCUMENT SCANNER
         */
        async void ScanningUIClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            var configuration = new DocumentScannerConfiguration
            {
                CameraPreviewMode        = CameraPreviewMode.FitIn,
                IgnoreBadAspectRatio     = true,
                MultiPageEnabled         = true,
                PolygonColor             = Color.Red,
                PolygonColorOK           = Color.Green,
                BottomBarBackgroundColor = Color.Blue,
                PageCounterButtonTitle   = "%d Page(s)",
                //DocumentImageSizeLimit = new Size(2000, 3000),
                // see further customization configs...
            };
            var result = await SBSDK.UI.LaunchDocumentScannerAsync(configuration);

            if (result.Status == OperationResult.Ok)
            {
                foreach (var page in result.Pages)
                {
                    Pages.Instance.List.Add(page);
                }
                await Navigation.PushAsync(new ImageResultsPage());
            }
        }
        async void WorkflowMRZClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            var workflow = SBSDK.UI.CreateWorkflow();
            var ratios   = new[] {
                new AspectRatio(85.0, 54.0),     // ID card
                new AspectRatio(125.0, 88.0)     // Passport
            };

            workflow.AddScanMachineReadableZoneStep(
                title: "Scan ID card or passport",
                message: "Please align your ID card or passport in the frame.",
                requiredAspectRatios: ratios,
                resultValidationHandler: (o, args) =>
            {
                var result = args.Result as IWorkflowMachineReadableZoneResult;
                if (result.MachineReadableZone == null ||
                    result.MachineReadableZone.CheckDigitsCount == 0)
                {
                    var message = "Recognition was not successful. " +
                                  "Please try again and scan the side with MRZ area.";
                    args.SetError(message, ValidationErrorShowMode.Alert);
                    return;
                }
                // run some additional validations here
                //result.MachineReadableZone.Fields...
            }
                );

            await RunWorkflow(workflow);
        }
 void SetBarcodeFormatsFilterClicked(object sender, EventArgs e)
 {
     if (!SDKUtils.CheckLicense(this))
     {
         return;
     }
     Navigation.PushAsync(new BarcodeSelectorPage());
 }
 void ViewImageResultsClicked(object sender, EventArgs e)
 {
     if (!SDKUtils.CheckLicense(this))
     {
         return;
     }
     Navigation.PushAsync(new ImageResultsPage());
 }
        async void OnSaveButtonClick(object sender, EventArgs e)
        {
            var    parameters = new string[] { "PDF", "PDF with OCR", "TIFF (1-bit, B&W)" };
            string action     = await DisplayActionSheet("Save Image as", "Cancel", null, parameters);

            if (action == null || action.Equals("Cancel"))
            {
                return;
            }

            (Content as AbsoluteLayout).RaiseChild(Loader);
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }
            if (!SDKUtils.CheckDocuments(this, Pages.Instance.DocumentSources))
            {
                return;
            }

            if (action.Equals(parameters[0]))
            {
                var fileUri = await SBSDK.Operations
                              .CreatePdfAsync(Pages.Instance.DocumentSources, PDFPageSize.FixedA4);

                ViewUtils.Alert(this, "Success: ", "Wrote documents to: " + fileUri.AbsolutePath);
            }
            else if (action.Equals(parameters[1]))
            {
                string path        = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                string pdfFilePath = Path.Combine(path, Guid.NewGuid() + ".pdf");
                var    languages   = new[] { "en" };
                var    result      = await SBSDK.Operations.PerformOcrAsync(Pages.Instance.DocumentSources, languages, pdfFilePath);

                // Or do something else with the results: result.Pages...
                ViewUtils.Alert(this, "PDF with OCR layer stored: ", pdfFilePath);
            }
            else if (action.Equals(parameters[2]))
            {
                var fileUri = await SBSDK.Operations.WriteTiffAsync(
                    Pages.Instance.DocumentSources,
                    new TiffOptions { OneBitEncoded = true, Dpi = 300, Compression = TiffCompressionOptions.CompressionCcittT6 }
                    );

                ViewUtils.Alert(this, "Success: ", "Wrote documents to: " + fileUri.AbsolutePath);
            }

            (Content as AbsoluteLayout).LowerChild(Loader);
        }
        async void ImportandDetectBarcodesClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }
            ImageSource source = await Scanbot.ImagePicker.Forms.ImagePicker.Instance.Pick();

            if (source != null)
            {
                var barcodes = await SBSDK.Operations.DetectBarcodesFrom(source);

                await Navigation.PushAsync(new BarcodeResultsPage(source, barcodes));
            }
        }
        async void OnCropButtonClick(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }
            if (!SDKUtils.CheckPage(this, Pages.Instance.SelectedPage))
            {
                return;
            }

            var result = await SBSDK.UI.LaunchCroppingScreenAsync(Pages.Instance.SelectedPage);

            Image.Source = null;
            Image.Source = Pages.Instance.SelectedPage.Document;
        }
        /**
         * MISCELLANEOUS
         */
        async void CleanupClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            await SBSDK.Operations.CleanUp();

            Pages.Instance.List.Clear();

            var message = "Cleanup done. All scanned images " +
                          "and generated files (PDF, TIFF, etc) have been removed.";

            ViewUtils.Alert(this, "Cleanup complete!", message);
        }
        async void EHICScannerClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            var configuration = new HealthInsuranceCardConfiguration {
            };
            var result        = await SBSDK.UI.LaunchHealthInsuranceCardScannerAsync(configuration);

            if (result.Status == OperationResult.Ok)
            {
                var message = SDKUtils.ParseEHICResult(result);
                ViewUtils.Alert(this, "MRZ Scanner result", message);
            }
        }
        async void FilterButtonClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            var action = await DisplayActionSheet(
                "Filter", "Cancel", null, Enum.GetNames(typeof(ImageFilter))
                );

            ImageFilter filter;

            Enum.TryParse(action, out filter);
            CurrentFilter = filter;

            Image.Source = await SBSDK.Operations
                           .ApplyImageFilterAsync(Image.Source, filter);
        }
        async void ImportButtonClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            ImageSource source = await ImagePicker.Forms.ImagePicker.Instance.Pick();

            if (source != null)
            {
                // Import the selected image as original image and create a Page object
                var importedPage = await SBSDK.Operations.CreateScannedPageAsync(source);

                // Run document detection on it
                await importedPage.DetectDocumentAsync();

                Pages.Instance.List.Add(importedPage);
            }
        }
        async void WorkflowQRClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            var workflow = SBSDK.UI.CreateWorkflow();

            workflow.AddScanBarcodeStep(
                "Scan Step 1/2", "Please scan a QR code.",
                new[] { BarcodeFormat.QrCode }, new AspectRatio(1.0, 1.0)
                );

            workflow.AddScanDocumentPageStep(
                "Scan Step 2/2",
                "Please scan a document.");

            await RunWorkflow(workflow);
        }
        /**
         * WORKFLOWS
         */
        async void MRZScannerClicked(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }

            MrzScannerConfiguration configuration = new MrzScannerConfiguration
            {
                FinderWidthRelativeToDeviceWidth  = 0.95,
                FinderHeightRelativeToDeviceWidth = 0.2,
            };

            var result = await SBSDK.UI.LaunchMrzScannerAsync(configuration);

            if (result.Status == OperationResult.Ok)
            {
                var message = SDKUtils.ParseMRZResult(result);
                ViewUtils.Alert(this, "MRZ Scanner result", message);
            }
        }
        async void OnFilterButtonClick(object sender, EventArgs e)
        {
            if (!SDKUtils.CheckLicense(this))
            {
                return;
            }
            if (!SDKUtils.CheckPage(this, Pages.Instance.SelectedPage))
            {
                return;
            }

            var buttons = Enum.GetNames(typeof(ImageFilter));
            var action  = await DisplayActionSheet("Filter", "Cancel", null, buttons);

            ImageFilter filter;

            Enum.TryParse(action, out filter);
            CurrentFilter = filter;

            await Pages.Instance.SelectedPage.SetFilterAsync(filter);

            Image.Source = Pages.Instance.SelectedPage.DocumentPreview;
        }
        async Task RunWorkflow(IWorkflow workflow)
        {
            var config = new WorkflowScannerConfiguration
            {
                IgnoreBadAspectRatio = true,
            };
            var result = await SBSDK.UI.LaunchWorkflowScannerAsync(workflow, config);

            if (result.Status == OperationResult.Ok)
            {
                var results = result.Results;

                ViewUtils.Alert(this, "Result:", SDKUtils.ParseWorkflowResults(results));

                foreach (var item in results)
                {
                    // Not all StepResults contain a captured page, try to find the one that has it
                    if (item.CapturedPage != null)
                    {
                        Pages.Instance.List.Add(item.CapturedPage);
                    }
                }
            }
        }