import { AspectRatio } from '../common/Common';
import { DeepPartial, PartiallyConstructible } from '../../utils';

/**
Configuration of the scanning interface's viewfinder, serving as guidance to the user.
*/
export class ViewFinderConfiguration extends PartiallyConstructible {
  /**
    Determines whether the viewfinder is visible or not.
    Default is true
    */
  public visible: boolean = true;
  /**
    The visual appearance of the viewfinder.
    */
  public style: FinderStyle = new FinderCorneredStyle({
    strokeColor: '?sbColorSurface',
    strokeWidth: 2.0,
    cornerRadius: 10.0,
  });
  /**
    The color of the viewfinder overlay.
    Default is "?sbColorSurfaceLow"
    */
  public overlayColor: string = '?sbColorSurfaceLow';
  /**
    The viewfinder's aspect ratio.
    */
  public aspectRatio: AspectRatio = new AspectRatio({ width: 1.0, height: 1.0 });

  /** @param source {@displayType `DeepPartial<ViewFinderConfiguration>`} */
  public constructor(source: DeepPartial<ViewFinderConfiguration> = {}) {
    super();
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.style !== undefined) {
      this.style = FinderStyle.From(source.style);
    }
    if (source.overlayColor !== undefined) {
      this.overlayColor = source.overlayColor;
    }
    if (source.aspectRatio !== undefined) {
      this.aspectRatio = new AspectRatio(source.aspectRatio);
    }
  }
}

export type FinderStyle = FinderCorneredStyle | FinderStrokedStyle;
/** @internal */
export namespace FinderStyle {
  /** @internal */
  export function From(source: { [key: string]: any }): FinderStyle {
    const _type = source._type;
    switch (_type) {
      case 'FinderCorneredStyle':
        return new FinderCorneredStyle(source);
      case 'FinderStrokedStyle':
        return new FinderStrokedStyle(source);
      default:
        throw `Unknown child class name: ${_type}`;
    }
  }
}

/**
A variant of the viewfinder displaying only the four corners of the scanning area.
*/
export class FinderCorneredStyle extends PartiallyConstructible {
  public readonly _type: 'FinderCorneredStyle' = 'FinderCorneredStyle';
  /**
    The color of the viewfinder corner's outlines.
    Default is "#FFFFFFFF"
    */
  public strokeColor: string = '#FFFFFFFF';
  /**
    The width of the viewfinder corner's outlines.
    Default is 3.0
    */
  public strokeWidth: number = 3.0;
  /**
    The radius of the viewfinder's corners.
    Default is 10.0
    */
  public cornerRadius: number = 10.0;

  /** @param source {@displayType `DeepPartial<FinderCorneredStyle>`} */
  public constructor(source: DeepPartial<FinderCorneredStyle> = {}) {
    super();
    if (source.strokeColor !== undefined) {
      this.strokeColor = source.strokeColor;
    }
    if (source.strokeWidth !== undefined) {
      this.strokeWidth = source.strokeWidth;
    }
    if (source.cornerRadius !== undefined) {
      this.cornerRadius = source.cornerRadius;
    }
  }
}

/**
A variant of the viewfinder displaying a full outline of the scanning area.
*/
export class FinderStrokedStyle extends PartiallyConstructible {
  public readonly _type: 'FinderStrokedStyle' = 'FinderStrokedStyle';
  /**
    The color of the viewfinder corner's outlines.
    Default is "#FFFFFFFF"
    */
  public strokeColor: string = '#FFFFFFFF';
  /**
    The width of the viewfinder corner's outlines.
    Default is 3.0
    */
  public strokeWidth: number = 3.0;
  /**
    The radius of the viewfinder's corners.
    Default is 10.0
    */
  public cornerRadius: number = 10.0;

  /** @param source {@displayType `DeepPartial<FinderStrokedStyle>`} */
  public constructor(source: DeepPartial<FinderStrokedStyle> = {}) {
    super();
    if (source.strokeColor !== undefined) {
      this.strokeColor = source.strokeColor;
    }
    if (source.strokeWidth !== undefined) {
      this.strokeWidth = source.strokeWidth;
    }
    if (source.cornerRadius !== undefined) {
      this.cornerRadius = source.cornerRadius;
    }
  }
}
