package fanch.multijeu.numbers.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.Serializable;

import fanch.multijeu.R;
import fanch.multijeu.common.core.Saveable;
import fanch.multijeu.common.core.SerializedObject;
import fanch.multijeu.findwords.fragments.SimpleWordViewFragment;
import fanch.multijeu.numbers.data.Expression;
import fanch.multijeu.numbers.data.ExpressionSet;
import fanch.multijeu.numbers.data.ExpressionSetGenerator;
import fanch.multijeu.numbers.fragment.NumberFragment;

import static android.view.View.GONE;
import static fanch.multijeu.numbers.data.ExpressionSetGenerator.EASY;

public class NumberActivity extends AppCompatActivity implements NumberFragment.NumberFragmentDriver {

    public static final int RESULT_CODE = 0x10203040;

    protected NumberFragment mFragment;


    protected Button mPass;
    protected TextView mPoints;
    protected TextView mPointsLabel;
    protected TextView mScore;
    protected TextView mScoreLabel;

    public enum GameMode {
        FREE,
        SCORE,
        ONE_SHOT
    }

    public static class Result extends Saveable {
        public int           best;
        public boolean       won;
        public Attrs         attrs;
        public int           result;
    }

    public static class Attrs extends NumberFragment.Attrs{
        public int difficulty=EASY;
        public boolean isCorrectable=true;
        public GameMode mode=GameMode.SCORE;
    }

    protected static class Model{
        ExpressionSetGenerator esg;
        int score;
        int point=10;
        int best;
        public Attrs attrs=new Attrs();
    }
    protected Model m = new Model();


    public static void start(Context c, Attrs a)
    {
        Intent in = new Intent(c, NumberActivity.class);
        in.putExtra("attrs", (Serializable) a.saveToSerializedObject());
        c.startActivity(in);
    }

    public static void start(Context c, int d)
    {
        Attrs a = new Attrs();
        a.difficulty=d;
        a.isCorrectable=true;
        a.time=-1;
        a.mode=GameMode.FREE;
        a.style= NumberFragment.PadStyle.NON_ASSISTED;
        start(c, a);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_number);

        mPass=findViewById(R.id.btn_pass);
        mPoints=findViewById(R.id.tv_points);
        mPointsLabel=findViewById(R.id.tv_points_label);
        mScore=findViewById(R.id.tv_score);
        mScoreLabel=findViewById(R.id.tv_score_label);

        m.attrs = ((SerializedObject<Attrs>)getIntent().getSerializableExtra("attrs")).newObject();
        if(m.attrs==null) m.attrs=new Attrs();
        initMode();

        m.esg = new ExpressionSetGenerator(m.attrs.difficulty);
        NumberFragment.Attrs attr =
                ((SerializedObject<NumberFragment.Attrs>)getIntent().
                        getSerializableExtra("attrs")).newObject();
        if (savedInstanceState == null) {
            mFragment= NumberFragment.newInstance(attr);
            getSupportFragmentManager().beginTransaction().replace(R.id.fragmentNumber, mFragment).commitNow();
            mFragment.setListener(this);
        }
    }

    protected void initMode()
    {
        switch(m.attrs.mode)
        {
            case FREE:
                mPass.setVisibility(View.VISIBLE);
                mScore.setVisibility(View.VISIBLE);
                mScoreLabel.setVisibility(View.VISIBLE);
                mPoints.setVisibility(GONE);
                mPointsLabel.setVisibility(GONE);
                break;

            case SCORE:
                mPass.setVisibility(View.VISIBLE);
                mScore.setVisibility(View.VISIBLE);
                mScoreLabel.setVisibility(View.VISIBLE);
                mPoints.setVisibility(View.VISIBLE);
                mPointsLabel.setVisibility(View.VISIBLE);
                break;

            case ONE_SHOT:
            default:
                mPass.setVisibility(GONE);
                mScore.setVisibility(GONE);
                mScoreLabel.setVisibility(GONE);
                mPoints.setVisibility(GONE);
                mPointsLabel.setVisibility(GONE);
                break;
        }
    }



    public void setMode(GameMode mm)
    {
        m.attrs.mode=mm;
        initMode();
    }

    public void setPadStyle(NumberFragment.PadStyle p)
    {
        m.attrs.style=p;
    }




    public void finish(boolean status, Expression e)
    {
        int x =0;
        if(e==null) x = m.esg.peek().resultInt;
        else x=e.compute();
        finish(status, x);
    }

    public void finish(boolean status, int e)
    {
        Intent n = new Intent();
        Result r = new Result();
        r.result=m.esg.peek().resultInt;
        r.best=e;
        r.won=status;
        r.attrs=m.attrs;
        n.putExtra("result", r);
        setResult(RESULT_CODE, n);
        finish();
    }

    @Override
    public void onLoose(ExpressionSet s, Expression e) {
        if(m.attrs.isCorrectable) mFragment.correct();
        if(m.attrs.mode==GameMode.SCORE)
        {
            m.score-=2;
            int b=m.esg.peek().resultInt;
            if(e!=null){
                b=m.esg.peek().resultInt-e.compute();
            }
            if(b<0) b=-b;
            m.point-=b;
            if(!m.attrs.isCorrectable && m.point<0)
                finish(false, e);
        }else if(m.attrs.mode==GameMode.ONE_SHOT)
        {
            if(!m.attrs.isCorrectable)
                finish(false, e);
        }else if(m.attrs.mode==GameMode.FREE)
        {
            m.score-=2;
        }
        mPass.setVisibility(GONE);

    }

    @Override
    public void onWin(ExpressionSet s, Expression e) {
        if(m.attrs.mode==GameMode.ONE_SHOT)
        {
            finish(true, e);
        }else{
            m.score++;
            m.point++;
            newGame();
        }
    }

    @Override
    public void onCorrectFinish() {
        if( (m.attrs.mode==GameMode.SCORE && m.point<0)
                || m.attrs.mode==GameMode.ONE_SHOT)
        {
            finish(false, m.best);
        }
        else
            newGame();
    }

    @Override
    public void onAnimationFinish() {
        updateUi(true);
    }

    @Override
    public void onFragmentInit() {
        newGame();
    }

    @Override
    public void onBestChanged(int value) {
        m.best=value;
        updateUi(true);
    }

    public void updateUi(boolean showPass)
    {
        mPoints.setText(""+m.point);
        mScore.setText(""+m.score);
    }

    protected void newGame()
    {
        ExpressionSet es = m.esg.generate();
        m.best=es.resultInt;
        mFragment.newGame(es);
        initMode();
        updateUi(false);
    }

    public void onNew(View view) {
        final Context c = this;
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Êtes-vous sur ?");

        if(m.attrs.mode==GameMode.SCORE) {
            int b = m.esg.peek().resultInt-m.best;
            if(b<0) b=-b;
            if(m.point-b<0)
                builder.setMessage("Si vous passez, vous perdrez ! voulez vous continuer ?");
            else
                builder.setMessage("Si vous passez, vous perdrez "+b+" points, voulez vous continuer");
        }
        else builder.setMessage("Si vous passez partie, elle sera perdue ?");
        builder.setPositiveButton("Oui", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                AlertDialog.Builder builder2 = new AlertDialog.Builder(c);
                builder2.setTitle("Voir la réponse ?");
                builder2.setMessage("Voulez vous voir la réponse ?");
                builder2.setPositiveButton("Oui", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                        if(m.attrs.isCorrectable)
                            mFragment.correct();
                        else
                            onCorrectFinish();
                    }
                });
                builder2.setNegativeButton("Non", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        newGame();
                    }
                });
                AlertDialog dialog2 = builder2.create();
                dialog2.show();
            }
        });
        builder.setNegativeButton("Non", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                // User cancelled the dialog
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
    }
}
