package com.atr.tedit.dialog;

import android.annotation.TargetApi;
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
//import android.support.v7.view.ContextThemeWrapper;
import androidx.appcompat.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;

import com.atr.tedit.R;
import com.atr.tedit.TEditActivity;
import com.atr.tedit.mainstate.Editor;

/**
 * @author Adam T. Ryder
 * <a href="https://www.inventati.org/1337gallery">https://www.inventati.org/1337gallery</a>
 */

public abstract class Sidebar {
    public static final int DIR_TO_LEFT = 0;
    public static final int DIR_TO_RIGHT = 1;

    public static final int ANIMLENGTH = 240;

    protected final TEditActivity ctx;
    protected final Handler handler = new Handler(Looper.getMainLooper());

    protected final ViewGroup container;
    protected final View sidebar;

    private boolean animating = false;
    private boolean open = false;
    protected int direction;

    public Sidebar(TEditActivity ctx, int direction, int layout, int rootId) {
        this.ctx = ctx;
        this.direction = direction;

        ViewGroup rootVG = ctx.findViewById(R.id.activity_tedit);
        LayoutInflater inflater = ctx.getLayoutInflater().cloneInContext(new ContextThemeWrapper(ctx, R.style.Dark_Roast));
        container = inflater.inflate(layout, rootVG, true).findViewById(rootId);

        sidebar = container.getChildAt(0);
        container.setVisibility(View.INVISIBLE);
        container.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return isOpen();
            }
        });

        int width = (ctx.getMetrics().widthPixels > ctx.getMetrics().heightPixels)
                ? ctx.getMetrics().heightPixels : ctx.getMetrics().widthPixels;
        ViewGroup.LayoutParams lp = sidebar.getLayoutParams();
        lp.width = Math.round(width * 0.8f);
        sidebar.setLayoutParams(lp);
    }

    public boolean isAnimating() {
        return animating;
    }

    public boolean isOpen() {
        return open;
    }

    public boolean canOpen() {
        return !isOpen() && !animating;
    }

    public boolean canClose() {
        return isOpen() && !animating;
    }

    public void open(boolean animate) {
        if (open)
            return;

        open = true;
        container.setVisibility(View.VISIBLE);
        ctx.closeContextMenu();

        if (ctx.getFrag() instanceof Editor) {
            Editor editor = (Editor)ctx.getFrag();
            editor.clearFocus();
            editor.hideCursor(true);
        }

        if (!animate) {
            ((TransitionDrawable)container.getBackground()).startTransition(0);
            return;
        }

        animating = true;
        ((TransitionDrawable)container.getBackground()).startTransition(ANIMLENGTH);
        switch(direction) {
            case DIR_TO_RIGHT:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    animateGL(sidebar, 0, sidebar.getWidth(), new DecelerateInterpolator());
                } else
                    animateSW(sidebar, 0, sidebar.getWidth(), new DecelerateInterpolator());
                break;
            default:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    animateGL(sidebar, 0, -sidebar.getWidth(), new DecelerateInterpolator());
                } else
                    animateSW(sidebar, 0, -sidebar.getWidth(), new DecelerateInterpolator());
        }

        handler.postDelayed(new Runnable() {
            public void run() {
                animating = false;
            }
        }, ANIMLENGTH);
    }

    public void close(boolean animate) {
        if (!open)
            return;

        open = false;
        if (!animate) {
            container.setVisibility(View.INVISIBLE);
            return;
        }

        animating = true;
        ((TransitionDrawable)container.getBackground()).reverseTransition(ANIMLENGTH);
        switch(direction) {
            case DIR_TO_RIGHT:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    animateGL(sidebar, sidebar.getWidth(), 0, new DecelerateInterpolator());
                } else
                    animateSW(sidebar, sidebar.getWidth(), 0, new DecelerateInterpolator());
                break;
            default:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    animateGL(sidebar, -sidebar.getWidth(), 0, new DecelerateInterpolator());
                } else
                    animateSW(sidebar, -sidebar.getWidth(), 0, new DecelerateInterpolator());
        }

        handler.postDelayed(new Runnable() {
            public void run() {
                animating = false;
                if (ctx.getFrag() instanceof Editor)
                    ((Editor) ctx.getFrag()).hideCursor(false);
            }
        }, ANIMLENGTH);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    protected void animateGL(View displayView, int to, int from, Interpolator interpolator) {
        displayView.setTranslationX(from);
        displayView.animate().translationX(to).setDuration(ANIMLENGTH).setInterpolator(interpolator).withLayer().start();
    }

    protected void animateSW(View displayView, int to, int from, Interpolator interpolator) {
        displayView.setTranslationX(from);
        displayView.animate().translationX(to).setDuration(ANIMLENGTH).setInterpolator(interpolator).start();
    }

    public void setState(Bundle savedInstanceState) {
        open = true;
        container.setVisibility(View.VISIBLE);
        ((TransitionDrawable)container.getBackground()).startTransition(0);
    }

    public abstract void saveState(Bundle outState);
}
