/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import {
  BlurTransformation,
  BrightnessTransformation,
  CropSquareTransformation,
  CropTransformation,
  GrayScaleTransformation,
  ImageKnifeComponent,
  ImageKnifeOption,
  InvertTransformation,
  KuwaharaTransformation,
  MaskTransformation,
  MultiTransTransformation,
  PixelationTransformation,
  PixelMapTransformation,
  SepiaTransformation,
  SketchTransformation,
  SwirlTransformation,
  ToonTransformation,
  VignetterTransformation
} from '@ohos/libraryimageknife';
import { collections } from '@kit.ArkTS'

@Entry
@Component
struct ImageTransformation {
  @State imageKnifeOption: ImageKnifeOption = {
    loadSrc: $r('app.media.pngSample'),
    placeholderSrc: $r('app.media.loading'),
    errorholderSrc: $r('app.media.app_icon'),
    objectFit: ImageFit.Contain
  }
  @State isRound: boolean = false;
  @State isContrast: boolean = false;
  @State isRotate: boolean = false;
  isBlur: boolean = false
  isBrightness: boolean = false
  isGrayScale: boolean = false;
  isInvert: boolean = false;
  isToon: boolean = false;
  isCropCircle: boolean = false;
  isCropCircleWithBorder: boolean = false;
  isKuwahara: boolean = false;
  isPixelation: boolean = false;
  isSketch: boolean = false;
  isSwirl: boolean = false;
  isVignetter: boolean = false;
  isCropSquare: boolean = false;
  isCropTop: boolean = false;
  isCropCenter: boolean = false;
  isCropBottom: boolean = false;
  isMask: boolean = false;
  isSepia: boolean = false;

  build() {
    Scroll() {
      Column() {
        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox1', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isBlur = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Blur_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox2', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isBrightness = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Highlighting_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox3', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isGrayScale = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Ashing_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox4', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isInvert = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Inverse_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox5', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isToon = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Animation_filter_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox6', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isCropCircle = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Crop_circular_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox7', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isCropCircleWithBorder = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Crop_circular_with_border_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox8', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isContrast = value;
            })
            .width(30)
            .height(30)
          Text($r('app.string.Contrast_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox9', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isSepia = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Black_ink_filtering_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox10', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isRotate = value;
            })
            .width(30)
            .height(30)
          Text($r('app.string.Rotate')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox11', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isRound = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Corners')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox12', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isKuwahara = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Kuwahara_Filter_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox13', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isPixelation = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Pixelated_Filter_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox14', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isSketch = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Sketch_Filter_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox15', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isSwirl = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Distortion_Filter_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox16', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isVignetter = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Decorative_Filter_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox17', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isCropSquare = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Square_cutting_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox18', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isCropTop = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Top_cutting_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox19', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isCropCenter = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Middle_cutting_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox20', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isCropBottom = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Bottom_cutting_effect')).fontSize(20)
        }

        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
          Checkbox({ name: 'checkbox21', group: 'checkboxGroup' })
            .selectedColor(0x39a2db)
            .shape(CheckBoxShape.ROUNDED_SQUARE)
            .onChange((value: boolean) => {
              this.isMask = value;
              this.updateImageKnifeOption();
            })
            .width(30)
            .height(30)
          Text($r('app.string.Mask_effect')).fontSize(20)
        }

        if (this.isContrast) {
          ImageKnifeComponent({
            imageKnifeOption: this.imageKnifeOption
          })
            .width(300)
            .height(300)
            .rotate({ angle: this.isRotate ? 90 : 0 })
            .contrast(12)
            .backgroundColor(Color.Pink)
        } else {
          ImageKnifeComponent({
            imageKnifeOption: this.imageKnifeOption
          }).width(300)
            .height(300)
            .rotate({ angle: this.isRotate ? 90 : 0 })
            .backgroundColor(Color.Pink)
        }
      }
    }
    .height('100%')
    .width('100%')
  }

  updateImageKnifeOption() {
    let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>()
    if (this.isBlur) {
      transformations.push(new BlurTransformation(5));
    }
    if (this.isBrightness) {
      transformations.push(new BrightnessTransformation(0.2));
    }
    if (this.isGrayScale) {
      transformations.push(new GrayScaleTransformation());
    }
    if (this.isInvert) {
      transformations.push(new InvertTransformation());
    }
    if (this.isToon) {
      transformations.push(new ToonTransformation(0.3, 10.0));
    }
    if (this.isKuwahara) {
      transformations.push(new KuwaharaTransformation(10));
    }
    if (this.isPixelation) {
      transformations.push(new PixelationTransformation(5.0));
    }
    if (this.isSketch) {
      transformations.push(new SketchTransformation());
    }
    if (this.isSwirl) {
      transformations.push(new SwirlTransformation(200, 1.0, [0.5, 0.5]));
    }
    if (this.isVignetter) {
      transformations.push(new VignetterTransformation([0.5, 0.5], [0.0, 0.0, 0.0], [0.3, 0.75]));
    }
    if (this.isCropSquare) {
      transformations.push(new CropSquareTransformation());
    }
    if (this.isCropTop) {
      transformations.push(new CropTransformation(100, 100, 0));
    }
    if (this.isCropCenter) {
      transformations.push(new CropTransformation(100, 100, 1));
    }
    if (this.isCropBottom) {
      transformations.push(new CropTransformation(100, 100, 2));
    }
    if (this.isSepia) {
      transformations.push(new SepiaTransformation());
    }
    if (this.isMask) {
      transformations.push(new MaskTransformation($r('app.media.mask_starfish')));
    }
    this.imageKnifeOption = {
      loadSrc: $r('app.media.pngSample'),
      placeholderSrc: $r('app.media.loading'),
      errorholderSrc: $r('app.media.app_icon'),
      objectFit: ImageFit.Contain,
      border: { radius: this.isRound ? { topLeft: 50, bottomRight: 50 } : 0 },
      transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined
    }
    if (this.isCropCircle) {
      this.imageKnifeOption.objectFit = ImageFit.Cover;
      this.imageKnifeOption.border = { radius: 150 };
    }
    if (this.isCropCircleWithBorder) {
      this.imageKnifeOption.objectFit = ImageFit.Cover;
      this.imageKnifeOption.border = { radius: 150, color: Color.Red, width: 5 };
    }
  }
}