package com.cygnusa.hyperm.droppy;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.RotateDrawable;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.cygnusa.hyperm.R;
import com.cygnusa.hyperm.util.GlobalData;

import java.util.ArrayList;
import java.util.List;


public class EasyDialog {
    private Context context;
    public static final int GRAVITY_TOP = 0;
    public static final int GRAVITY_BOTTOM = 1;
    private Dialog dialog;
    private int[] location;
    private int gravity;
    private View contentView;
    private ImageView ivTriangle;
    private LinearLayout llContent;
    private boolean touchOutsideDismiss;
    private RelativeLayout rlOutsideBackground;
    DroppyMenuPopup droppyMenu;

    public EasyDialog(Context context, DroppyMenuPopup droppyMenu) {
        this.droppyMenu = droppyMenu;
        initDialog(context);
    }

    private void initDialog(final Context context) {
        this.context = context;
        LayoutInflater layoutInflater = ((Activity) context)
                .getLayoutInflater();
        View dialogView = layoutInflater.inflate(R.layout.layout_dialog, null);
        ViewTreeObserver viewTreeObserver = dialogView.getViewTreeObserver();
        viewTreeObserver
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        relocation(location);
                    }
                });
        rlOutsideBackground = (RelativeLayout) dialogView
                .findViewById(R.id.rlOutsideBackground);


        rlOutsideBackground.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (touchOutsideDismiss && dialog != null) {
                    onDialogDismiss();
                }
                return false;
            }
        });

        ivTriangle = (ImageView) dialogView.findViewById(R.id.ivTriangle);
        llContent = (LinearLayout) dialogView.findViewById(R.id.llContent);
//        dialog = new Dialog(context, isFullScreen() ? android.R.style.Theme_Translucent_NoTitleBar_Fullscreen
//                : android.R.style.Theme_Translucent_NoTitleBar);


        dialog = new Dialog(context, R.style.AppTheme);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        dialog.setContentView(dialogView);
        animatorSetForDialogShow = new AnimatorSet();
        animatorSetForDialogDismiss = new AnimatorSet();
        objectAnimatorsForDialogShow = new ArrayList<Animator>();
        objectAnimatorsForDialogDismiss = new ArrayList<Animator>();
        ini();
    }

    private void ini() {
        this.setLocation(new int[]{0, 0}).setGravity(GRAVITY_BOTTOM)
                .setTouchOutsideDismiss(true)
                .setOutsideColor(Color.TRANSPARENT)
                .setBackgroundColor(Color.BLUE, Color.WHITE)
                .setMatchParent(true).setMarginLeftAndRight(24, 24);
    }

    public EasyDialog setLayout(View layout) {
        if (layout != null) {
            this.contentView = layout;
        }
        return this;
    }

    public EasyDialog setLayoutResourceId(int layoutResourceId) {
        View view = ((Activity) context).getLayoutInflater().inflate(
                layoutResourceId, null);
        setLayout(view);
        return this;
    }

    public EasyDialog setLocation(int[] location) {
        this.location = location;
        return this;
    }

    public EasyDialog setLocationByAttachedView(View attachedView) {
        if (attachedView != null) {
            this.attachedView = attachedView;
            int[] attachedViewLocation = new int[2];
            attachedView.getLocationOnScreen(attachedViewLocation);
            attachedViewLocation[0] = attachedViewLocation[0]
                    + attachedView.getWidth() / 2;
            switch (gravity) {
                case GRAVITY_BOTTOM:
                    attachedViewLocation[1] = attachedViewLocation[1]
                            + attachedView.getHeight();
                    break;
                case GRAVITY_TOP:

                    break;
            }
            setLocation(attachedViewLocation);
        }
        return this;
    }

    private View attachedView = null;

    public EasyDialog setGravity(int gravity) {
        if (gravity != GRAVITY_BOTTOM && gravity != GRAVITY_TOP) {
            gravity = GRAVITY_BOTTOM;
        }
        this.gravity = gravity;
        switch (this.gravity) {
            case GRAVITY_BOTTOM:
                ivTriangle.setBackgroundResource(R.drawable.triangle_bottom);
                break;
            case GRAVITY_TOP:
                ivTriangle.setBackgroundResource(R.drawable.triangle_top);
                break;
        }
        llContent.setBackgroundResource(R.drawable.round_corner_bg);
        if (attachedView != null) {
            this.setLocationByAttachedView(attachedView);
        }
        this.setBackgroundColor(backgroundColor, Color.WHITE);
        return this;
    }

    public EasyDialog setMatchParent(boolean matchParent) {
        ViewGroup.LayoutParams layoutParams = llContent.getLayoutParams();
        layoutParams.width = matchParent ? ViewGroup.LayoutParams.MATCH_PARENT
                : ViewGroup.LayoutParams.WRAP_CONTENT;
        llContent.setLayoutParams(layoutParams);
        return this;
    }

    public EasyDialog setMarginLeftAndRight(int left, int right) {
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) llContent
                .getLayoutParams();
        layoutParams.setMargins(left, 0, right, 0);
        llContent.setLayoutParams(layoutParams);
        return this;
    }

    public EasyDialog setTouchOutsideDismiss(boolean touchOutsideDismiss) {
        this.touchOutsideDismiss = touchOutsideDismiss;
        return this;
    }

    public EasyDialog setOutsideColor(int color) {
        rlOutsideBackground.setBackgroundColor(color);
        return this;
    }

    private int backgroundColor;

    public EasyDialog setBackgroundColor(int color, int shapeColor) {
        backgroundColor = color;
        LayerDrawable drawableTriangle = (LayerDrawable) ivTriangle
                .getBackground();
        GradientDrawable shapeTriangle = (GradientDrawable) (((RotateDrawable) drawableTriangle
                .findDrawableByLayerId(R.id.shape_id)).getDrawable());
        if (shapeTriangle != null) {
            shapeTriangle.setColor(shapeColor);
        } else {
            GlobalData.showToast(context, "shape is null", Toast.LENGTH_SHORT).show();
        }
        GradientDrawable drawableRound = (GradientDrawable) llContent
                .getBackground();
        if (drawableRound != null) {
            drawableRound.setColor(color);
        }
        return this;
    }

    public EasyDialog show() {
        if (dialog != null) {
            if (contentView == null) {
                throw new RuntimeException("");
            }
            llContent.addView(contentView);
            dialog.show();
            onDialogShowing();
        }
        return this;
    }

    public View getTipViewInstance() {
        return rlOutsideBackground.findViewById(R.id.rlParentForAnimate);
    }

    public static final int DIRECTION_X = 0;
    public static final int DIRECTION_Y = 1;

    public EasyDialog setAnimationTranslationShow(int direction, int duration,
                                                  float... values) {
        return setAnimationTranslation(true, direction, duration, values);
    }

    public EasyDialog setAnimationTranslationDismiss(int direction,
                                                     int duration, float... values) {
        return setAnimationTranslation(false, direction, duration, values);
    }

    private EasyDialog setAnimationTranslation(boolean isShow, int direction,
                                               int duration, float... values) {
        if (direction != DIRECTION_X && direction != DIRECTION_Y) {
            direction = DIRECTION_X;
        }
        String propertyName = "";
        switch (direction) {
            case DIRECTION_X:
                propertyName = "translationX";
                break;
            case DIRECTION_Y:
                propertyName = "translationY";
                break;
        }
        ObjectAnimator animator = ObjectAnimator.ofFloat(
                rlOutsideBackground.findViewById(R.id.rlParentForAnimate),
                propertyName, values).setDuration(duration);
        if (isShow) {
            objectAnimatorsForDialogShow.add(animator);
        } else {
            objectAnimatorsForDialogDismiss.add(animator);
        }
        return this;
    }

    public EasyDialog setAnimationAlphaShow(int duration, float... values) {
        return setAnimationAlpha(true, duration, values);
    }

    public EasyDialog setAnimationAlphaDismiss(int duration, float... values) {
        return setAnimationAlpha(false, duration, values);
    }

    private EasyDialog setAnimationAlpha(boolean isShow, int duration,
                                         float... values) {
        ObjectAnimator animator = ObjectAnimator.ofFloat(
                rlOutsideBackground.findViewById(R.id.rlParentForAnimate),
                "alpha", values).setDuration(duration);
        if (isShow) {
            objectAnimatorsForDialogShow.add(animator);
        } else {
            objectAnimatorsForDialogDismiss.add(animator);
        }
        return this;
    }

    private AnimatorSet animatorSetForDialogShow;
    private AnimatorSet animatorSetForDialogDismiss;
    private List<Animator> objectAnimatorsForDialogShow;
    private List<Animator> objectAnimatorsForDialogDismiss;

    private void onDialogShowing() {
        if (animatorSetForDialogShow != null
                && objectAnimatorsForDialogShow != null
                && objectAnimatorsForDialogShow.size() > 0) {
            animatorSetForDialogShow.playTogether(objectAnimatorsForDialogShow);
            animatorSetForDialogShow.start();
        }
        // ObjectAnimator.ofFloat(rlOutsideBackground.findViewById(R.id.rlParentForAnimate),
        // "scaleX", 0.3f, 1.0f).setDuration(500).start();
        // ObjectAnimator.ofFloat(rlOutsideBackground.findViewById(R.id.rlParentForAnimate),
        // "scaleY", 0.3f, 1.0f).setDuration(500).start();
    }

    private void onDialogDismiss() {
        if (animatorSetForDialogDismiss.isRunning()) {
            return;
        }
        if (animatorSetForDialogDismiss != null
                && objectAnimatorsForDialogDismiss != null
                && objectAnimatorsForDialogDismiss.size() > 0) {
            animatorSetForDialogDismiss
                    .playTogether(objectAnimatorsForDialogDismiss);
            animatorSetForDialogDismiss.start();
            animatorSetForDialogDismiss
                    .addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            dialog.dismiss();
                            try {
                                droppyMenu.dismiss();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {

                        }
                    });
        } else {
            dialog.dismiss();
            try {
                droppyMenu.dismiss();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    public void dismiss() {
        if (dialog != null && dialog.isShowing()) {
            onDialogDismiss();
        }
    }

    private void relocation(int[] location) {
        ivTriangle.setX(location[0] - ivTriangle.getWidth() / 2);
        ivTriangle.setY(location[1] - ivTriangle.getHeight() / 2
                - (isFullScreen() ? 0.0f : getStatusBarHeight()));
        switch (gravity) {
            case GRAVITY_BOTTOM:
                llContent.setY(location[1] - ivTriangle.getHeight() / 2
                        - (isFullScreen() ? 0.0f : getStatusBarHeight())
                        + ivTriangle.getHeight());
                break;
            case GRAVITY_TOP:
                llContent.setY(location[1] - llContent.getHeight()
                        - (isFullScreen() ? 0.0f : getStatusBarHeight())
                        - ivTriangle.getHeight() / 2);
                break;
        }
        int triangleCenterX = (int) (ivTriangle.getX() + ivTriangle.getWidth() / 2);
        int contentWidth = llContent.getWidth();
        int rightMargin = getScreenWidth() - triangleCenterX;
        int leftMargin = getScreenWidth() - rightMargin;
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) llContent
                .getLayoutParams();
        int availableLeftMargin = leftMargin - layoutParams.leftMargin;
        int availableRightMargin = rightMargin - layoutParams.rightMargin;
        int x = 0;
        if (contentWidth / 2 <= availableLeftMargin
                && contentWidth / 2 <= availableRightMargin) {
            x = triangleCenterX - contentWidth / 2;
        } else {
            if (availableLeftMargin <= availableRightMargin) {
                x = layoutParams.leftMargin;
            } else {
                x = getScreenWidth()
                        - (contentWidth + layoutParams.rightMargin);
            }
        }
        llContent.setX(x);
    }

    private int getScreenWidth() {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        return metrics.widthPixels;
    }

    private int getStatusBarHeight() {
        int result = 0;
        int resourceId = context.getResources().getIdentifier(
                "status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    public boolean isFullScreen() {
        int flg = ((Activity) context).getWindow().getAttributes().flags;
        boolean flag = false;
        if ((flg & 1024) == 1024) {
            flag = true;
        }
        return flag;
    }

    public EasyDialog setCancelable(boolean cancelable) {
        dialog.setCancelable(cancelable);
        return this;
    }
}
