import { Background } from "../styling/background";
import {
    SliderBase, valueProperty, minValueProperty, maxValueProperty,
    colorProperty, backgroundColorProperty, backgroundInternalProperty, Color
} from "./slider-common";

export * from "./slider-common";

interface OwnerSeekBar extends android.widget.SeekBar {
    owner: Slider;
}

let SeekBar: typeof android.widget.SeekBar;
let SeekBarChangeListener: android.widget.SeekBar.OnSeekBarChangeListener;

function initializeModule(): void {
    if (!SeekBar) {
        SeekBar = android.widget.SeekBar;
    }

    if (!SeekBarChangeListener) {
        @Interfaces([android.widget.SeekBar.OnSeekBarChangeListener])
        class SeekBarChangeListenerImpl extends java.lang.Object implements android.widget.SeekBar.OnSeekBarChangeListener {
            constructor() {
                super();
                return global.__native(this);
            }

            onProgressChanged(seekBar: OwnerSeekBar, progress: number, fromUser: boolean): void {
                const owner = seekBar.owner;
                if (!owner._supressNativeValue) {
                    const newValue = progress + owner.minValue;
                    valueProperty.nativeValueChange(owner, newValue);
                }
            }

            onStartTrackingTouch(seekBar: OwnerSeekBar): void {
                //
            }

            onStopTrackingTouch(seekBar: OwnerSeekBar): void {
                //
            }
        }

        SeekBarChangeListener = new SeekBarChangeListenerImpl();
    }
}

function getListener(): android.widget.SeekBar.OnSeekBarChangeListener {
    return SeekBarChangeListener;
}

export class Slider extends SliderBase {
    _supressNativeValue: boolean;
    nativeViewProtected: OwnerSeekBar;

    public createNativeView() {
        initializeModule();
        const nativeView = new SeekBar(this._context);
        const listener = getListener();
        nativeView.setOnSeekBarChangeListener(listener);
        return nativeView;
    }

    public initNativeView(): void {
        super.initNativeView();
        this.nativeViewProtected.owner = this;
    }

    public disposeNativeView() {
        this.nativeViewProtected.owner = null;
        super.disposeNativeView();
    }

    public resetNativeView(): void {
        super.resetNativeView();
        const nativeView = this.nativeViewProtected;
        nativeView.setMax(100);
        nativeView.setProgress(0);
        nativeView.setKeyProgressIncrement(1);
    }

    /**
     * There is no minValue in Android. We simulate this by subtracting the minValue from the native value and maxValue. 
     * We need this method to call native setMax and setProgress methods when minValue property is changed,
     * without handling the native value changed callback.
     */
    private setNativeValuesSilently() {
        this._supressNativeValue = true;
        const nativeView = this.nativeViewProtected;
        try {
            nativeView.setMax(this.maxValue - this.minValue);
            nativeView.setProgress(this.value - this.minValue);
        } finally {
            this._supressNativeValue = false;
        }
    }

    [valueProperty.setNative](value: number) {
        this.setNativeValuesSilently();
    }

    [minValueProperty.setNative](value: number) {
       this.setNativeValuesSilently();
    }

    [maxValueProperty.getDefault](): number {
        return 100;
    }
    [maxValueProperty.setNative](value: number) {
        this.setNativeValuesSilently();
    }

    [colorProperty.getDefault](): number {
        return -1;
    }
    [colorProperty.setNative](value: number | Color) {
        if (value instanceof Color) {
            this.nativeViewProtected.getThumb().setColorFilter(value.android, android.graphics.PorterDuff.Mode.SRC_IN);
        } else {
            this.nativeViewProtected.getThumb().clearColorFilter();
        }
    }

    [backgroundColorProperty.getDefault](): number {
        return -1;
    }
    [backgroundColorProperty.setNative](value: number | Color) {
        if (value instanceof Color) {
            this.nativeViewProtected.getProgressDrawable().setColorFilter(value.android, android.graphics.PorterDuff.Mode.SRC_IN);
        } else {
            this.nativeViewProtected.getProgressDrawable().clearColorFilter();
        }
    }

    [backgroundInternalProperty.getDefault](): Background {
        return null;
    }
    [backgroundInternalProperty.setNative](value: Background) {
        //
    }
}