package app.mar.activities;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.Timer;
import java.util.TimerTask;

import app.mar.game.Area;
import app.mar.game.Bomb;
import app.mar.game.Game;
import app.mar.game.Resource;
import app.mar.game.Stage;
import app.mar.game.challenges.Challenge;
import app.mar.game.challenges.Indice;
import app.mar.game.scheduler.ChallengeTask;
import app.mar.game.scheduler.Scheduler;
import app.mar.game.scheduler.SpecialTask;
import app.mar.game.scheduler.Task;
import app.mar.utils.AndroidResources;
import app.mar.utils.L;


public class HostActivity extends Activity implements ChallengeDriver{
    public static final int REQUEST_CODE = 25;
    protected Game mGame;
    protected TextView mUITimeLeft;
    protected TextView mUICode;
    protected Button   mUIButtonVideos;
    protected Button   mUIButtonIndice;
    protected Button   mUIButtonValid;

    protected QCMFragment mQCMFragment;
    protected QRCodeFragment mQRCodeFragment;
    protected QuestionFragment mQuestionFragment;
    protected ChallengeFragment mCurrentFragment;
    protected Challenge mCurrentChallenge;

    private static final int ACTIVITY_RESULT_RESOURCE_VIEWER_SCHEDULER = 2;

    private Timer mTimer;
    private Runnable mTimerTick = new Runnable() {
        public void run() {
            if(!mGame.getBomb().hasExplosed())
            {
                mUITimeLeft.setText(mGame.getBomb().getTimeBeforeBoom());
            }else
            {
                mUITimeLeft.setText("BOOM !");
                onExplose();
                mTimer.cancel();
            }
        }
    };

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

        mQCMFragment = QCMFragment.newInstance();
        mQuestionFragment = QuestionFragment.newInstance();
        mQRCodeFragment = QRCodeFragment.newInstance();
        mUIButtonVideos = (Button) findViewById(R.id.btn_videos);
        mUIButtonIndice = (Button) findViewById(R.id.btn_indice);
        mUIButtonValid = (Button) findViewById(R.id.btn_valid);

        mGame=Game.game();


        mUITimeLeft = findViewById(R.id.tv_car);
        mUICode = findViewById(R.id.tv_code);

        mTimer = new Timer();
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                timerCallback();
            }

        }, 0, 1000);

        updateCode();

        if(mGame.getCurrentStageIndex()<0) { //noueau jeu
            mGame.nextStage(this);
            mGame.getScheduler().schedule(this, mGame);
        }
        else
        {
            initFromLoad();
        }
    }

    public void initFromLoad()
    {

        Log.e("____SAVE____", "Load 0: Last"+mGame.getScheduler().getLastTask()+" --> "+mGame.getScheduler());
        mGame.getScheduler().undo();
        Log.e("____SAVE____", "Load 1: Last"+mGame.getScheduler().getLastTask()+" --> "+mGame.getScheduler());
        mGame.getScheduler().schedule(this, mGame);
    }

    public   void setFragment(Challenge c)
    {
        Class type = c.getStartWith();
        mCurrentChallenge=c;
        ChallengeFragment f = null;

        if(type.isInstance(mQCMFragment))
            f= mQCMFragment;
        else if(type.isInstance(mQRCodeFragment))
            f= mQRCodeFragment;
        else if(type.isInstance(mQuestionFragment))
            f= mQuestionFragment;
        else {
            throw new RuntimeException("Erreur: La classe de fragment est null");
        }

        if(f!=mCurrentFragment)
        {
            mCurrentFragment=f;
            FragmentManager fm = getFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            ft.replace(R.id.container, mCurrentFragment);
            ft.commit();
        }
        else
        {
            onReady(c);
        }
    }

    @Override
    public void onReady(Challenge chall) {
        mCurrentFragment.initChallenge(chall);
    }



    @Override
    public double getDistanceWith(Area a) {
        return a.getDistance(mGame.getPlayer());
    }

    @Override
    public double getAccuracy() {
        return mGame.getPlayer().getSensorsManager().getPosition().getAccuracy();
    }


    @Override
    public void onFragmentInteraction(Uri uri) {}


    public void onTryDisarm(View v)
    {
        Scheduler sched = mGame.getScheduler();
        sched.undo();
        sched.prepend(SpecialTask.BOMB);
        sched.schedule(this, mGame);
    }


    private void timerCallback()
    {
        this.runOnUiThread(mTimerTick);
    }

    private void updateCode()
    {
        Log.e("--------", "Bomb: "+mGame.getBomb().getPasswordKnown());
        mUICode.setText(mGame.getBomb().getPasswordKnown());
    }

    public void onClickValid(View v)
    {
        if(mCurrentFragment!=null)
        {
            if(mCurrentFragment.check())
            {
                challengeValidate(mCurrentFragment.getChallenge(),  mGame, this);
            }else if(!mCurrentFragment.getChallenge().isMandatory())
            {
                mGame.getBomb().addTime(-mCurrentFragment.getChallenge().getPenality());
                challengeValidate(mCurrentFragment.getChallenge(),  mGame, this);
            }
        }
    }

    public void onClickVideos(View v)
    {
        Intent intent = new Intent(this, ResourceListActivity.class);
        intent.putExtra("inventaire", mGame.getInventaire());
        startActivity(intent);
    }

    public void onClickDisarm(View v)
    {

    }

    public void onClickIndice(View v)
    {
        if(mCurrentFragment!=null)
        {
            Indice ind = mCurrentFragment.showIndice();
            if(ind!=null && ind.getPenality()>0)
                mGame.getBomb().addTime(-ind.getPenality());

            if(!mCurrentFragment.getChallenge().hasNextIndice())
                mUIButtonIndice.setVisibility(View.INVISIBLE);
            save();
        }
    }

    public void onExplose()
    {
        setFailed();
    }

    public void setVisibilityView(int res, int state)
    {
        View v = findViewById(res);
        if(v!=null) v.setVisibility(state);
    }

    public void setVisibilityView(int[] res, int state)
    {
        for(int i=0; i<res.length; i++)
            setVisibilityView(res[i], state);
    }

    public Challenge nextChallenge() {

        Challenge c = mGame.nextChallenge(this);
        Stage s = mGame.getCurrentStage();
        Log.e("___SCHEDULER_PRESQUE","\t->"+ c);
        if(c!=null)
        {
            mGame.getScheduler().append(c);
        }else if(s!=null) //new stage
        {
            Log.i("----", "New Stage !");
            mGame.getBomb().addKnownCharacter(s.getCharIndex());
            updateCode();
        }else{
            Scheduler sched = mGame.getScheduler();
            sched.undo();
            sched.prepend(SpecialTask.BOMB);
            sched.schedule(this, mGame);
        }
        return c;
    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        int x =23;
        x++;
        switch (requestCode)
        {
            case CreditsActivity.REQUEST_CODE:
            case ModelViewerActivity.REQUEST_CODE:
            case MediaViewerAcitvity.REQUEST_CODE:
            case TestVideoActivity.REQUEST_CODE:
            case BombActivity.REQUEST_CODE:
            case ImageViewerActivity.REQUEST_CODE:
                mGame.getScheduler().schedule(this, mGame);
                save();
            break;


        }
    }

    public void startResource(Resource r)
    {
        Intent intent = AndroidResources.getViewerIntent(this, r);
        startActivityForResult(intent, AndroidResources.getViewerRequestCode(r));
    }


    @Override
    public void challengeValidate(Challenge c, Game g, ChallengeDriver dri) {
        mGame.getBomb().addKnownCharacter(c.getCharIndex());
        updateCode();
        nextChallenge();

        mGame.getScheduler().schedule(this, mGame);
        save();
    }

    public Challenge currentChallenge() {
        return mCurrentChallenge;
    }

    public void setFinished()
    {

    }

    public void setFailed()
    {
        Intent intent = new Intent(this, CreditsActivity.class);
        startActivity(intent);
        finish();
    }

    @Override
    public Activity getActivity() {
        return this;
    }

    @Override
    public void load() {
        Log.e("____SAVE____", "Load: Last"+mGame.getScheduler().getLastTask()+" --> "+mGame.getScheduler());
        mGame = Game.load(this);
        Game.setGame(mGame);
    }

    @Override
    public void save() {
        Log.e("____SAVE____", "Save: Last"+mGame.getScheduler().getLastTask()+" --> "+mGame.getScheduler());
        mGame.save(this);
    }

    @Override
    public void startLocalisation() {
        mGame.newSensorManager(this);
    }

    @Override
    public void resumeLocalisation() {
        mGame.onResume();
    }

    @Override
    public void pauseLocalisation() {
        mGame.onPause(this);
    }

    @Override
    public void onBackPressed()
    {
        if(mCurrentFragment==null || mCurrentFragment.onBackPressed())
            super.onBackPressed();
    }
}