/*
 * Copyright © Dynamsoft Corporation. All rights reserved.
 */

#if RCT_NEW_ARCH_ENABLED

#import "RNDynamsoftCameraViewComponentView.h"

#import <react/renderer/components/DynamsoftCaptureVisionSpec/ComponentDescriptors.h>
#import <react/renderer/components/DynamsoftCaptureVisionSpec/EventEmitters.h>
#import <react/renderer/components/DynamsoftCaptureVisionSpec/Props.h>
#import <react/renderer/components/DynamsoftCaptureVisionSpec/RCTComponentViewHelpers.h>

#import "RCTFabricComponentsPlugins.h"

// The generated Swift header (below) declares every @objc Swift class in this module in one
// go, so the ObjC superclasses/protocols of *all* of them must already be visible here too —
// mirrors the imports used by the other JSI .mm files in this pod for the same reason.
#import <React/RCTEventEmitter.h>
#import <React/RCTViewManager.h>
#import <DynamsoftCaptureVisionSpec/DynamsoftCaptureVisionSpec.h>
#import <DynamsoftCaptureVisionBundle/DynamsoftCaptureVisionBundle.h>

// Auto-generated Objective-C interface for this pod's Swift sources. The header name is
// derived from the pod's module name (hyphens become underscores) — verify against the
// build log if this ever fails to resolve.
#if __has_include("dynamsoft_capture_vision_react_native-Swift.h")
#import "dynamsoft_capture_vision_react_native-Swift.h"
#else
#import <dynamsoft_capture_vision_react_native/dynamsoft_capture_vision_react_native-Swift.h>
#endif

using namespace facebook::react;

@interface RNDynamsoftCameraViewComponentView () <RCTDynamsoftCameraViewViewProtocol>
@end

@implementation RNDynamsoftCameraViewComponentView {
  RNDynamsoftCameraView *_innerView;
}

+ (ComponentDescriptorProvider)componentDescriptorProvider
{
  return concreteComponentDescriptorProvider<DynamsoftCameraViewComponentDescriptor>();
}

- (instancetype)initWithFrame:(CGRect)frame
{
  if (self = [super initWithFrame:frame]) {
    static const auto defaultProps = std::make_shared<const DynamsoftCameraViewProps>();
    _props = defaultProps;

    _innerView = [[RNDynamsoftCameraView alloc] initWithFrame:self.bounds];
    _innerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.contentView = _innerView;
  }
  return self;
}

- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
{
  static const auto defaultProps = std::make_shared<const DynamsoftCameraViewProps>();
  const auto &oldViewProps = oldProps
      ? *std::static_pointer_cast<DynamsoftCameraViewProps const>(oldProps)
      : *defaultProps;
  const auto &newViewProps = props
      ? *std::static_pointer_cast<DynamsoftCameraViewProps const>(props)
      : *defaultProps;

  if (oldViewProps.visibleLayerIds != newViewProps.visibleLayerIds) {
    NSMutableArray<NSNumber *> *layerIds = [NSMutableArray arrayWithCapacity:newViewProps.visibleLayerIds.size()];
    for (auto layerId : newViewProps.visibleLayerIds) {
      [layerIds addObject:@(layerId)];
    }
    _innerView.visibleLayerIds = layerIds;
  }

  if (oldViewProps.scanRegionMaskVisible != newViewProps.scanRegionMaskVisible) {
    _innerView.scanRegionMaskVisible = newViewProps.scanRegionMaskVisible;
  }

  if (oldViewProps.scanLaserVisible != newViewProps.scanLaserVisible) {
    _innerView.scanLaserVisible = newViewProps.scanLaserVisible;
  }

  const auto &oldTorchButton = oldViewProps.torchButton;
  const auto &newTorchButton = newViewProps.torchButton;
  if (oldTorchButton.location.x != newTorchButton.location.x ||
      oldTorchButton.location.y != newTorchButton.location.y ||
      oldTorchButton.location.width != newTorchButton.location.width ||
      oldTorchButton.location.height != newTorchButton.location.height ||
      oldTorchButton.visible != newTorchButton.visible ||
      oldTorchButton.torchOnImageBase64 != newTorchButton.torchOnImageBase64 ||
      oldTorchButton.torchOffImageBase64 != newTorchButton.torchOffImageBase64) {
    _innerView.torchButton = @{
      @"location" : @{
        @"x" : @(newTorchButton.location.x),
        @"y" : @(newTorchButton.location.y),
        @"width" : @(newTorchButton.location.width),
        @"height" : @(newTorchButton.location.height),
      },
      @"visible" : @(newTorchButton.visible),
      @"torchOnImageBase64" : [NSString stringWithUTF8String:newTorchButton.torchOnImageBase64.c_str()],
      @"torchOffImageBase64" : [NSString stringWithUTF8String:newTorchButton.torchOffImageBase64.c_str()],
    };
  }

  if (oldViewProps.torchButtonVisible != newViewProps.torchButtonVisible) {
    _innerView.torchButtonVisible = newViewProps.torchButtonVisible;
  }

  const auto &oldToggleButton = oldViewProps.cameraToggleButton;
  const auto &newToggleButton = newViewProps.cameraToggleButton;
  if (oldToggleButton.location.x != newToggleButton.location.x ||
      oldToggleButton.location.y != newToggleButton.location.y ||
      oldToggleButton.location.width != newToggleButton.location.width ||
      oldToggleButton.location.height != newToggleButton.location.height ||
      oldToggleButton.cameraToggleImageBase64 != newToggleButton.cameraToggleImageBase64) {
    _innerView.cameraToggleButton = @{
      @"location" : @{
        @"x" : @(newToggleButton.location.x),
        @"y" : @(newToggleButton.location.y),
        @"width" : @(newToggleButton.location.width),
        @"height" : @(newToggleButton.location.height),
      },
      @"cameraToggleImageBase64" : [NSString stringWithUTF8String:newToggleButton.cameraToggleImageBase64.c_str()],
    };
  }

  if (oldViewProps.cameraToggleButtonVisible != newViewProps.cameraToggleButtonVisible) {
    _innerView.cameraToggleButtonVisible = newViewProps.cameraToggleButtonVisible;
  }

  [super updateProps:props oldProps:oldProps];
}

@end

Class<RCTComponentViewProtocol> DynamsoftCameraViewCls(void)
{
  return RNDynamsoftCameraViewComponentView.class;
}

#endif // RCT_NEW_ARCH_ENABLED
