//
//  BarcodeScannerView.m
//  RNBarcodeZXing
//
//  Created by LUANLUU on 07/06/2021.
//  Copyright © 2021 Facebook. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "BarcodeScannerView.h"

@implementation BarcodeScannerView {
  CGAffineTransform _captureSizeTransform;
}

- (id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self) {
    self.capture = [[ZXCapture alloc] init];
    self.capture.sessionPreset = AVCaptureSessionPreset1920x1080;
    self.capture.camera = self.capture.back;
    self.capture.focusMode = AVCaptureFocusModeContinuousAutoFocus;
    self.capture.delegate = self;
    
    self.scanning = NO;
    
    [self.layer addSublayer:self.capture.layer];
  }
  return self;
}

- (void)layoutSubviews
{
  [super layoutSubviews];
  self.capture.layer.frame = self.frame;
  if (_isFirstApplyOrientation) return;
  _isFirstApplyOrientation = TRUE;
  [self applyOrientation];
}

#pragma mark - View Controller Methods
- (void)dealloc {
  [self.capture.layer removeFromSuperlayer];
}

- (UIInterfaceOrientation) getUIInterfaceOrientation {
  if (@available(iOS 13.0, *)) {
    UIWindow *firstWindow = [[[UIApplication sharedApplication] windows] firstObject];
    if (firstWindow == nil) {
      return UIInterfaceOrientationUnknown;
    }
    UIWindowScene *windowScene = firstWindow.windowScene;
    if (windowScene == nil){
      return UIInterfaceOrientationUnknown;
    }
    return windowScene.interfaceOrientation;
  }
  return [[UIApplication sharedApplication] statusBarOrientation];
}

#pragma mark - Private
- (void)applyOrientation {
  UIInterfaceOrientation orientation = [self getUIInterfaceOrientation];
  
  float scanRectRotation;
  float captureRotation;
  
  switch (orientation) {
    case UIInterfaceOrientationPortrait:
      captureRotation = 0;
      scanRectRotation = 90;
      break;
    case UIInterfaceOrientationLandscapeLeft:
      captureRotation = 90;
      scanRectRotation = 180;
      break;
    case UIInterfaceOrientationLandscapeRight:
      captureRotation = 270;
      scanRectRotation = 0;
      break;
    case UIInterfaceOrientationPortraitUpsideDown:
      captureRotation = 180;
      scanRectRotation = 270;
      break;
    default:
      captureRotation = 0;
      scanRectRotation = 90;
      break;
  }
  CGAffineTransform transform = CGAffineTransformMakeRotation((CGFloat) (captureRotation / 180 * M_PI));
  [self.capture setTransform:transform];
  [self.capture setRotation:scanRectRotation];
  
}

#pragma mark - Private Methods

- (NSString *)barcodeFormatToString:(ZXBarcodeFormat)format {
  switch (format) {
    case kBarcodeFormatAztec:
      return @"Aztec";
      
    case kBarcodeFormatCodabar:
      return @"CODABAR";
      
    case kBarcodeFormatCode39:
      return @"Code 39";
      
    case kBarcodeFormatCode93:
      return @"Code 93";
      
    case kBarcodeFormatCode128:
      return @"Code 128";
      
    case kBarcodeFormatDataMatrix:
      return @"Data Matrix";
      
    case kBarcodeFormatEan8:
      return @"EAN-8";
      
    case kBarcodeFormatEan13:
      return @"EAN-13";
      
    case kBarcodeFormatITF:
      return @"ITF";
      
    case kBarcodeFormatPDF417:
      return @"PDF417";
      
    case kBarcodeFormatQRCode:
      return @"QR Code";
      
    case kBarcodeFormatRSS14:
      return @"RSS 14";
      
    case kBarcodeFormatRSSExpanded:
      return @"RSS Expanded";
      
    case kBarcodeFormatUPCA:
      return @"UPCA";
      
    case kBarcodeFormatUPCE:
      return @"UPCE";
      
    case kBarcodeFormatUPCEANExtension:
      return @"UPC/EAN extension";
      
    default:
      return @"Unknown";
  }
}

#pragma mark - ZXCaptureDelegate Methods

- (void)captureCameraIsReady:(ZXCapture *)capture {
  self.scanning = YES;
}

- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result {
  if (!self.scanning) return;
  if (!result) return;
  
  NSString *format = [self barcodeFormatToString:result.barcodeFormat];
  NSString *display = [NSString stringWithFormat:@"Scanned!\n\nFormat: %@\n\nContents:\n%@", format, result.text];
  NSString *barcodes = [result.text length] != 0 ? result.text: @"UnknowBarcode";
  
  [[self delegate] onRead:self result:@{@"format": format, @"barcodes": barcodes}];
}

@end
