package fanch.multijeu.sudoku.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import fanch.multijeu.common.core.Saveable;
import fanch.multijeu.numbers.widget.GridLayout;
import fanch.multijeu.sudoku.listener.SudokuDriver;

public class SudokuOverlay extends ViewGroup implements View.OnClickListener {

    protected static final int BACKGROUND_COLOR=0x80000000;
    protected static final int BUTTON_OK_COLOR=0xff00afaf;
    protected static final int BUTTON_ERROR_COLOR=0xffff0000;
    protected static final int BUTTON_CLEAR_COLOR =0xffff0000;
    protected static final int ALL[]={0, 1,2,3,4,5,6,7,8,9};
    public static final int    CLEAR_CODE=0;

    public enum SelectMode {
        NO_ASSIST,
        DISABLE_BUTTON,
        COLOR_BUTTON
    }

    public static class Attrs extends Saveable {
        public SelectMode select=SelectMode.NO_ASSIST;
    }




    protected GridLayout mGrid;
    protected Button     mButtons[];
    protected int mGridWidth=3*66;
    protected int mGridHeight=4*66;
    protected int mLastClickX=0;
    protected int mLastClickY=0;

    protected SudokuCase mCurrentCase=null;
    protected int        mCurrentX=-1;
    protected int        mCurrentY=-1;

    private SudokuDriver mListener;
    protected Attrs      mAttrs = new Attrs();



    public SudokuOverlay(Context context) {
        super(context);
        init();
    }

    public SudokuOverlay(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public void init()
    {
        setVisibility(GONE);
        setBackgroundColor(BACKGROUND_COLOR);
        mGrid=new GridLayout(getContext());
        mGrid.setGridDimension(3,4);
        addView(mGrid);

        mButtons=new Button[10];
        for(int i=0; i<9; i++){
            mButtons[i+1] = createButton(i);
            mButtons[i+1].setText(""+(i+1));
            mGrid.addView(mButtons[i+1]);
        }

        mButtons[CLEAR_CODE] = createButton(9);
        mButtons[CLEAR_CODE].setText("C");
        mGrid.addView(mButtons[CLEAR_CODE]);

        setOnClickListener(this);

    }

    private Button createButton(int x) {
        Button b = new Button(getContext());
        b.setBackgroundColor(0xff00afaf);
        b.setPadding(0,0,0,0);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            b.setTextAlignment(TEXT_ALIGNMENT_CENTER);
        }
        b.setLayoutParams(new GridLayout.LayoutParams(x%3, x/3));
        b.setOnClickListener(this);
        return b;
    }



    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int W = r-l;
        final int H = b-t;

        double pcx = 0.5;
        double pcy = 0.5;

        mGridWidth=(int)(((float)getWidth())/3);
        mGridHeight= (int) (mGridWidth*1.333);

        int x =mLastClickX;
        int y = mLastClickY;
        final int dleft = (int) (mGridWidth*pcx);
        final int dright = (int) (mGridWidth*(1-pcx));
        final int dtop = (int) (mGridHeight*pcy);
        final int dbottom = (int) (mGridHeight*(1-pcy));



        if(x-dleft<0) x=dleft;
        if(y-dtop<0) y=dtop;
        if(x+dright>=W) x=W-dright;
        if(y+dbottom>=H) y= H-dbottom;
        mGrid.layout(x-dleft,y-dtop,
                x-dleft+mGridWidth,
                y-dtop+mGridHeight);

    }

    public void click(SudokuCase ca, int x, int y)
    {
        click(ca, x, y, ALL);
    }

    public void click(SudokuCase ca, int x, int y, int possible[])
    {
        if(mCurrentCase!=null)
        {
            cancel();
            return;
        }

        mCurrentCase=ca;
        mLastClickX=ca.getLeft();
        mLastClickY=ca.getTop();
        mCurrentX=x;
        mCurrentY=y;

        setAlpha(0);
        setVisibility(VISIBLE);
        setAnimAlpha(this, 1);
        for(int i=1; i<10; i++)
        {
            boolean present = false;
            for(int j=0; j<possible.length; j++)
                if(possible[j]==i){ present=true; break;}
            if(i!=CLEAR_CODE) {
                if (mAttrs.select == SelectMode.NO_ASSIST) {
                    showButton(mButtons[i]);
                    mButtons[i].setBackgroundColor(BUTTON_OK_COLOR);
                } else if (mAttrs.select == SelectMode.DISABLE_BUTTON) {
                    if (present) {
                        showButton(mButtons[i]);
                        mButtons[i].setBackgroundColor(BUTTON_OK_COLOR);
                    } else {
                        hideButton(mButtons[i]);
                        mButtons[i].setBackgroundColor(BUTTON_OK_COLOR);
                    }
                } else if (mAttrs.select == SelectMode.COLOR_BUTTON) {
                    showButton(mButtons[i]);
                    if (present) {
                        mButtons[i].setBackgroundColor(BUTTON_OK_COLOR);
                    } else {
                        mButtons[i].setBackgroundColor(BUTTON_ERROR_COLOR);
                    }
                }
            }else{
                if(present)
                {
                    showButton(mButtons[i]);
                    mButtons[CLEAR_CODE].setBackgroundColor(BUTTON_CLEAR_COLOR);
                }else{
                    hideButton(mButtons[i]);
                }

            }
        }

    }

    public void cancel()
    {
        final SudokuOverlay over = this;
        ObjectAnimator animation = ObjectAnimator.ofFloat(this, "alpha", 0);
        animation.setDuration(500);
        animation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                over.setVisibility(GONE);

                mCurrentCase=null;
                mCurrentX=0;
                mCurrentY=0;
            }
        });
        animation.start();
    }



    @Override
    public void onClick(View v) {
        if(mCurrentCase==null) return;
        if(v instanceof Button) {
            final int id = viewToId(v);
            mCurrentCase.setValue(id);
            if(mListener!=null) {
                mListener.setValue(mCurrentX, mCurrentY, id);
                mListener.valueChanged(mCurrentX, mCurrentY, id);
            }
            cancel();
        }else if(v==this)
        {
            cancel();
        }

    }

    public void setListener(SudokuDriver mListener) {
        this.mListener = mListener;
    }


    public void showButton(Button b)
    {
        setAnimAlpha(b,1);
        b.setEnabled(true);
    }

    public void hideButton(Button b)
    {
        setAnimAlpha(b, (float) 0.4);
        b.setEnabled(false);
    }

    public void setAnimAlpha(View b, float f)
    {
        ObjectAnimator animation = ObjectAnimator.ofFloat(b, "alpha", f);
        animation.setDuration(500);
        animation.start();
    }

    private int viewToId(View v)
    {
        for(int i=0; i<mButtons.length; i++)
            if(v==mButtons[i]) return i;
        return -1;
    }

    public void setAttrs(Attrs mAttrs) {
        this.mAttrs = mAttrs;
    }
}
