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

/**
Value palette describing the colors of the scanner screens.
*/
export class Palette extends PartiallyConstructible {
  /**
    The primary color used for enabled elements.
    Default is "#C8193C"
    */
  public sbColorPrimary: string = '#C8193C';
  /**
    The primary color used for disabled elements.
    Default is "#F5F5F5"
    */
  public sbColorPrimaryDisabled: string = '#F5F5F5';
  /**
    The color used to convey a negative meaning.
    Default is "#FF3737"
    */
  public sbColorNegative: string = '#FF3737';
  /**
    The color used to convey a positive meaning.
    Default is "#4EFFB4"
    */
  public sbColorPositive: string = '#4EFFB4';
  /**
    The color used to convey warnings.
    Default is "#FFCE5C"
    */
  public sbColorWarning: string = '#FFCE5C';
  /**
    The secondary color used for enabled elements.
    Default is "#FFEDEE"
    */
  public sbColorSecondary: string = '#FFEDEE';
  /**
    The secondary color used for disabled elements.
    Default is "#F5F5F5"
    */
  public sbColorSecondaryDisabled: string = '#F5F5F5';
  /**
    The color used for displaying elements on top of the primary color.
    Default is "#FFFFFF"
    */
  public sbColorOnPrimary: string = '#FFFFFF';
  /**
    The color used for displaying elements on top of the secondary color.
    Default is "#C8193C"
    */
  public sbColorOnSecondary: string = '#C8193C';
  /**
    The color used for surfaces.
    Default is "#FFFFFF"
    */
  public sbColorSurface: string = '#FFFFFF';
  /**
    The color used for outlines.
    Default is "#EFEFEF"
    */
  public sbColorOutline: string = '#EFEFEF';
  /**
    The alternative color used on top of surfaces.
    Default is "#707070"
    */
  public sbColorOnSurfaceVariant: string = '#707070';
  /**
    The color used on top of surfaces.
    Default is "#000000"
    */
  public sbColorOnSurface: string = '#000000';
  /**
    The color with a low alpha (transparency) value used for certain surfaces.
    Default is "#00000026"
    */
  public sbColorSurfaceLow: string = '#00000026';
  /**
    The color with a high alpha (transparency) value used for certain surfaces.
    Default is "#0000007A"
    */
  public sbColorSurfaceHigh: string = '#0000007A';
  /**
    The color with a very high alpha (transparency) value used to fill certain overlays.
    Default is "#000000A3"
    */
  public sbColorModalOverlay: string = '#000000A3';

  /** @param source {@displayType `DeepPartial<Palette>`} */
  public constructor(source: DeepPartial<Palette> = {}) {
    super();
    if (source.sbColorPrimary !== undefined) {
      this.sbColorPrimary = source.sbColorPrimary;
    }
    if (source.sbColorPrimaryDisabled !== undefined) {
      this.sbColorPrimaryDisabled = source.sbColorPrimaryDisabled;
    }
    if (source.sbColorNegative !== undefined) {
      this.sbColorNegative = source.sbColorNegative;
    }
    if (source.sbColorPositive !== undefined) {
      this.sbColorPositive = source.sbColorPositive;
    }
    if (source.sbColorWarning !== undefined) {
      this.sbColorWarning = source.sbColorWarning;
    }
    if (source.sbColorSecondary !== undefined) {
      this.sbColorSecondary = source.sbColorSecondary;
    }
    if (source.sbColorSecondaryDisabled !== undefined) {
      this.sbColorSecondaryDisabled = source.sbColorSecondaryDisabled;
    }
    if (source.sbColorOnPrimary !== undefined) {
      this.sbColorOnPrimary = source.sbColorOnPrimary;
    }
    if (source.sbColorOnSecondary !== undefined) {
      this.sbColorOnSecondary = source.sbColorOnSecondary;
    }
    if (source.sbColorSurface !== undefined) {
      this.sbColorSurface = source.sbColorSurface;
    }
    if (source.sbColorOutline !== undefined) {
      this.sbColorOutline = source.sbColorOutline;
    }
    if (source.sbColorOnSurfaceVariant !== undefined) {
      this.sbColorOnSurfaceVariant = source.sbColorOnSurfaceVariant;
    }
    if (source.sbColorOnSurface !== undefined) {
      this.sbColorOnSurface = source.sbColorOnSurface;
    }
    if (source.sbColorSurfaceLow !== undefined) {
      this.sbColorSurfaceLow = source.sbColorSurfaceLow;
    }
    if (source.sbColorSurfaceHigh !== undefined) {
      this.sbColorSurfaceHigh = source.sbColorSurfaceHigh;
    }
    if (source.sbColorModalOverlay !== undefined) {
      this.sbColorModalOverlay = source.sbColorModalOverlay;
    }
  }
}

/**
Configuration of the text field appearance.
*/
export class StyledText extends PartiallyConstructible {
  /**
    Determines whether the text field is visible or not.
    Default is true
    */
  public visible: boolean = true;
  /**
    The value of the text field.
    Default is ""
    */
  public text: string = '';
  /**
    The text color.
    Default is "#FFFFFF"
    */
  public color: string = '#FFFFFF';
  /**
    Determines whether to enable drop shadows for the text.
    Default is false
    */
  public useShadow: boolean = false;

  /** @param source {@displayType `DeepPartial<StyledText>`} */
  public constructor(source: DeepPartial<StyledText> = {}) {
    super();
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.text !== undefined) {
      this.text = source.text;
    }
    if (source.color !== undefined) {
      this.color = source.color;
    }
    if (source.useShadow !== undefined) {
      this.useShadow = source.useShadow;
    }
  }
}

/**
Configuration of the icon appearance.
*/
export class IconStyle extends PartiallyConstructible {
  /**
    Determines whether the icon is visible or not.
    Default is true
    */
  public visible: boolean = true;
  /**
    The icon color.
    Default is "#FFFFFF"
    */
  public color: string = '#FFFFFF';

  /** @param source {@displayType `DeepPartial<IconStyle>`} */
  public constructor(source: DeepPartial<IconStyle> = {}) {
    super();
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.color !== undefined) {
      this.color = source.color;
    }
  }
}

/**
Configuration of the icon appearance on a button.
*/
export class IconButton extends PartiallyConstructible {
  /**
    Determines whether the icon is visible on the button.
    Default is true
    */
  public visible: boolean = true;
  /**
    The icon color.
    Default is "#FFFFFF"
    */
  public color: string = '#FFFFFF';
  /**
    The text to be read when the button is selected through accessibility mode.
    Default is ""
    */
  public accessibilityDescription: string = '';

  /** @param source {@displayType `DeepPartial<IconButton>`} */
  public constructor(source: DeepPartial<IconButton> = {}) {
    super();
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.color !== undefined) {
      this.color = source.color;
    }
    if (source.accessibilityDescription !== undefined) {
      this.accessibilityDescription = source.accessibilityDescription;
    }
  }
}

/**
Configuration of the polygon appearance.
*/
export class PolygonStyle extends PartiallyConstructible {
  /**
    The color of the polygon outline.
    Default is "#FFFFFFFF"
    */
  public strokeColor: string = '#FFFFFFFF';
  /**
    The fill color of the polygon.
    Default is "#FFFFFF30"
    */
  public fillColor: string = '#FFFFFF30';
  /**
    The width of the polygon outline in dp.
    Default is 2.0
    */
  public strokeWidth: number = 2.0;
  /**
    The corner radius of the polygon in dp.
    Default is 0.0
    */
  public cornerRadius: number = 0.0;

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

/**
Configuration of the background appearance for buttons and hints.
*/
export class BackgroundStyle extends PartiallyConstructible {
  /**
    The color of the outline.
    Default is "#FFFFFFFF"
    */
  public strokeColor: string = '#FFFFFFFF';
  /**
    The fill color.
    Default is "#FFFFFF30"
    */
  public fillColor: string = '#FFFFFF30';
  /**
    The width of the outline in dp.
    Default is 2.0
    */
  public strokeWidth: number = 2.0;

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

/**
Configuration of the appearance for foreground elements (e.g. text and/or icons, etc).
*/
export class ForegroundStyle extends PartiallyConstructible {
  /**
    Determines whether the icon is visible or not.
    Default is true
    */
  public iconVisible: boolean = true;
  /**
    The color used for foreground elements.
    Default is "#FFFFFF"
    */
  public color: string = '#FFFFFF';
  /**
    Determines whether to use drop shadows for foreground elements.
    Default is false
    */
  public useShadow: boolean = false;

  /** @param source {@displayType `DeepPartial<ForegroundStyle>`} */
  public constructor(source: DeepPartial<ForegroundStyle> = {}) {
    super();
    if (source.iconVisible !== undefined) {
      this.iconVisible = source.iconVisible;
    }
    if (source.color !== undefined) {
      this.color = source.color;
    }
    if (source.useShadow !== undefined) {
      this.useShadow = source.useShadow;
    }
  }
}

/**
Configuration of the finder's aspect ratio.
*/
export class AspectRatio extends PartiallyConstructible {
  /**
    The width component of the aspect ratio.
    Default is 1.0
    */
  public width: number = 1.0;
  /**
    The height component of the aspect ratio.
    Default is 1.0
    */
  public height: number = 1.0;

  /** @param source {@displayType `DeepPartial<AspectRatio>`} */
  public constructor(source: DeepPartial<AspectRatio> = {}) {
    super();
    if (source.width !== undefined) {
      this.width = source.width;
    }
    if (source.height !== undefined) {
      this.height = source.height;
    }
  }
}

/**
Configuration of the badge.
*/
export class BadgeStyle extends PartiallyConstructible {
  /**
    Determines whether the badge is visible or not.
    Default is true
    */
  public visible: boolean = true;
  /**
    Configuration of the background appearance for the badge.
    */
  public background: BackgroundStyle = new BackgroundStyle({});
  /**
    The color of the badge's foreground (icon, text).
    Default is "?sbColorOnSurface"
    */
  public foregroundColor: string = '?sbColorOnSurface';

  /** @param source {@displayType `DeepPartial<BadgeStyle>`} */
  public constructor(source: DeepPartial<BadgeStyle> = {}) {
    super();
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.background !== undefined) {
      this.background = new BackgroundStyle(source.background);
    }
    if (source.foregroundColor !== undefined) {
      this.foregroundColor = source.foregroundColor;
    }
  }
}

/**
Configuration of the round button.
*/
export class RoundButton extends PartiallyConstructible {
  /**
    Determines whether the button is visible or not.
    Default is true
    */
  public visible: boolean = true;
  /**
    The text to be read when the button is selected through accessibility mode.
    Default is ""
    */
  public accessibilityDescription: string = '';
  /**
    The color of the button's background.
    Default is "#0000007A"
    */
  public backgroundColor: string = '#0000007A';
  /**
    The color of the button's foreground (icon, text).
    Default is "#FFFFFF"
    */
  public foregroundColor: string = '#FFFFFF';
  /**
    The color of the button's background when the button is active (selected, toggled).
    Default is "#FFCE5C"
    */
  public activeBackgroundColor: string = '#FFCE5C';
  /**
    The color of the button's foreground (icon, text) when the button is active (selected, toggled).
    Default is "#1C1B1F"
    */
  public activeForegroundColor: string = '#1C1B1F';

  /** @param source {@displayType `DeepPartial<RoundButton>`} */
  public constructor(source: DeepPartial<RoundButton> = {}) {
    super();
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.accessibilityDescription !== undefined) {
      this.accessibilityDescription = source.accessibilityDescription;
    }
    if (source.backgroundColor !== undefined) {
      this.backgroundColor = source.backgroundColor;
    }
    if (source.foregroundColor !== undefined) {
      this.foregroundColor = source.foregroundColor;
    }
    if (source.activeBackgroundColor !== undefined) {
      this.activeBackgroundColor = source.activeBackgroundColor;
    }
    if (source.activeForegroundColor !== undefined) {
      this.activeForegroundColor = source.activeForegroundColor;
    }
  }
}

/**
Configuration of the button with a badge.
*/
export class BadgedButton extends PartiallyConstructible {
  /**
    The color of the badge's background.
    Default is "#FFFFFF"
    */
  public badgeBackgroundColor: string = '#FFFFFF';
  /**
    The color of the badge's foreground (icon, text).
    Default is "#C8193C"
    */
  public badgeForegroundColor: string = '#C8193C';
  /**
    Determines whether the button is visible or not.
    Default is true
    */
  public visible: boolean = true;
  /**
    The color of the button's background.
    Default is "#0000007A"
    */
  public backgroundColor: string = '#0000007A';
  /**
    The color of the button's foreground (icon, text).
    Default is "#FFFFFF"
    */
  public foregroundColor: string = '#FFFFFF';
  /**
    The color of the button's background when the button is active (selected, toggled).
    Default is "#FFCE5C"
    */
  public activeBackgroundColor: string = '#FFCE5C';
  /**
    The color of the button's foreground (icon, text) when the button is active (selected, toggled).
    Default is "#1C1B1F"
    */
  public activeForegroundColor: string = '#1C1B1F';

  /** @param source {@displayType `DeepPartial<BadgedButton>`} */
  public constructor(source: DeepPartial<BadgedButton> = {}) {
    super();
    if (source.badgeBackgroundColor !== undefined) {
      this.badgeBackgroundColor = source.badgeBackgroundColor;
    }
    if (source.badgeForegroundColor !== undefined) {
      this.badgeForegroundColor = source.badgeForegroundColor;
    }
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.backgroundColor !== undefined) {
      this.backgroundColor = source.backgroundColor;
    }
    if (source.foregroundColor !== undefined) {
      this.foregroundColor = source.foregroundColor;
    }
    if (source.activeBackgroundColor !== undefined) {
      this.activeBackgroundColor = source.activeBackgroundColor;
    }
    if (source.activeForegroundColor !== undefined) {
      this.activeForegroundColor = source.activeForegroundColor;
    }
  }
}

/**
Configuration of the button.
*/
export class ButtonConfiguration extends PartiallyConstructible {
  /**
    Determines whether the button is visible or not.
    Default is true
    */
  public visible: boolean = true;
  /**
    The text to be displayed on the button.
    Default is ""
    */
  public text: string = '';
  /**
    The text to be read when the button is selected through accessibility mode.
    Default is ""
    */
  public accessibilityDescription: string = '';
  /**
    Configuration of the background appearance for the button.
    */
  public background: BackgroundStyle = new BackgroundStyle({});
  /**
    Configuration of the appearance for foreground elements (e.g. text and/or icons, etc) of the button.
    */
  public foreground: ForegroundStyle = new ForegroundStyle({});

  /** @param source {@displayType `DeepPartial<ButtonConfiguration>`} */
  public constructor(source: DeepPartial<ButtonConfiguration> = {}) {
    super();
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.text !== undefined) {
      this.text = source.text;
    }
    if (source.accessibilityDescription !== undefined) {
      this.accessibilityDescription = source.accessibilityDescription;
    }
    if (source.background !== undefined) {
      this.background = new BackgroundStyle(source.background);
    }
    if (source.foreground !== undefined) {
      this.foreground = new ForegroundStyle(source.foreground);
    }
  }
}

/**
Configuration for the popup menu items.
*/
export class PopupMenuItem extends PartiallyConstructible {
  /**
    The text to be displayed on the button.
    */
  public title: StyledText = new StyledText({});
  /**
    The text to be read when the button is selected through accessibility mode.
    Default is ""
    */
  public accessibilityDescription: string = '';
  /**
    Configuration of the icon appearance.
    */
  public icon: IconStyle = new IconStyle({});

  /** @param source {@displayType `DeepPartial<PopupMenuItem>`} */
  public constructor(source: DeepPartial<PopupMenuItem> = {}) {
    super();
    if (source.title !== undefined) {
      this.title = new StyledText(source.title);
    }
    if (source.accessibilityDescription !== undefined) {
      this.accessibilityDescription = source.accessibilityDescription;
    }
    if (source.icon !== undefined) {
      this.icon = new IconStyle(source.icon);
    }
  }
}

/**
Configuration of the button located on a bar.
*/
export class BarButtonConfiguration extends PartiallyConstructible {
  /**
    Determines whether the button is visible or not.
    Default is true
    */
  public visible: boolean = true;
  /**
    The text to be displayed on the button.
    */
  public title: StyledText = new StyledText({});
  /**
    The text to be read when the button is selected through accessibility mode.
    Default is ""
    */
  public accessibilityDescription: string = '';
  /**
    Configuration of the background appearance for the button.
    */
  public background: BackgroundStyle = new BackgroundStyle({});
  /**
    Configuration of the icon appearance.
    */
  public icon: IconStyle = new IconStyle({});

  /** @param source {@displayType `DeepPartial<BarButtonConfiguration>`} */
  public constructor(source: DeepPartial<BarButtonConfiguration> = {}) {
    super();
    if (source.visible !== undefined) {
      this.visible = source.visible;
    }
    if (source.title !== undefined) {
      this.title = new StyledText(source.title);
    }
    if (source.accessibilityDescription !== undefined) {
      this.accessibilityDescription = source.accessibilityDescription;
    }
    if (source.background !== undefined) {
      this.background = new BackgroundStyle(source.background);
    }
    if (source.icon !== undefined) {
      this.icon = new IconStyle(source.icon);
    }
  }
}

/**
Configure the orientation of the interface.

- `NONE`:
   Do not restrict the interface's orientation.
- `PORTRAIT`:
   Lock the orientation to portrait.
- `LANDSCAPE`:
   Lock the orientation to landscape.
*/
export type OrientationLockMode = 'NONE' | 'PORTRAIT' | 'LANDSCAPE';

/**
Configuration of the camera preview mode.

- `FIT_IN`:
   In this mode, the camera preview frames will be scaled to fit inside the layout view size - the full preview frame content will be visible, but unused edges might appear in the preview layout.
- `FILL_IN`:
   In this mode, the camera preview frames fill the entire layout view - the preview frames may contain additional content at the edges that are not visible in the preview layout.
*/
export type CameraPreviewMode = 'FIT_IN' | 'FILL_IN';

/**
Determines the successful detection sound.

- `MODERN_BEEP`:
   A modern beep sound.
- `CLASSIC_BEEP`:
   The old, classic beep sound.
*/
export type SoundType = 'MODERN_BEEP' | 'CLASSIC_BEEP';

/**
Configuration for the sound.
*/
export class Sound extends PartiallyConstructible {
  /**
    Determine whether the beep sound should be enabled or not when a barcode is detected.
    Default is true
    */
  public successBeepEnabled: boolean = true;
  /**
    Determines the successful detection sound.
    Default is MODERN_BEEP
    */
  public soundType: SoundType = 'MODERN_BEEP';

  /** @param source {@displayType `DeepPartial<Sound>`} */
  public constructor(source: DeepPartial<Sound> = {}) {
    super();
    if (source.successBeepEnabled !== undefined) {
      this.successBeepEnabled = source.successBeepEnabled;
    }
    if (source.soundType !== undefined) {
      this.soundType = source.soundType;
    }
  }
}

/**
Configure the vibration.
*/
export class Vibration extends PartiallyConstructible {
  /**
    Determine whether vibration should be enabled or not when a barcode is detected.
    Default is false
    */
  public enabled: boolean = false;

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

/**
Configuration of timeouts.
*/
export class Timeouts extends PartiallyConstructible {
  /**
    Sets the length of time, in milliseconds, when the scanner should auto close. Default is 0 (disabled).
    Default is 0
    */
  public autoCancelTimeout: number = 0;
  /**
    Sets the length of time, in milliseconds, that the first scan will be delayed by. Default is 0 (disabled).
    Default is 0
    */
  public initialScanDelay: number = 0;

  /** @param source {@displayType `DeepPartial<Timeouts>`} */
  public constructor(source: DeepPartial<Timeouts> = {}) {
    super();
    if (source.autoCancelTimeout !== undefined) {
      this.autoCancelTimeout = source.autoCancelTimeout;
    }
    if (source.initialScanDelay !== undefined) {
      this.initialScanDelay = source.initialScanDelay;
    }
  }
}
