package app.mar.activities;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

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

import app.mar.game.Area;
import app.mar.game.challenges.Challenge;
import app.mar.game.challenges.GeoIndice;
import app.mar.game.challenges.IGeoTreasure;
import app.mar.game.challenges.Indice;
import app.mar.game.challenges.TextIndice;
import app.mar.utils.L;

public abstract class ChallengeFragment extends Fragment {
    public abstract boolean check();
    protected abstract void onInitChallenge(Challenge c);
    protected abstract  void onResetUi();



    protected LinearLayout  mUITextIndices;
    protected TextView      mUIGeoIndice;
    protected LinearLayout  mUIGlobalIndice;
    protected Challenge     mChallenge;

    protected Timer         mTimer;

    private Runnable mTimerTick = new Runnable() {
        public void run() {
            onGeoUpdateTimer();
        }
    };


    public void resetUi()
    {
        if(mUIGeoIndice!=null)
        {
            mUIGeoIndice.setVisibility(View.GONE);
        }
        if(mUITextIndices!=null)
        {
            mUITextIndices.removeAllViews();
        }
        if(mUIGlobalIndice!=null)
        {
            mUIGlobalIndice.setVisibility(View.GONE);
        }
        onResetUi();
    }

    private void updateIndices()
    {
        ArrayList<Indice> inds = mChallenge.getIndices();
        int indInd = mChallenge.getIndiceIndex();
        if(inds.size()>0) mUIGlobalIndice.setVisibility(View.VISIBLE);
        for(int i=0; i<inds.size(); i++)
        {
            Indice ind = inds.get(i);
            if(!ind.isDiscovered()) return;
            if(ind instanceof GeoIndice && mUIGeoIndice!=null)
            {
                mUIGlobalIndice.setVisibility(View.VISIBLE);
                mUIGeoIndice.setVisibility(View.VISIBLE);
                startGeoUpdateTimer();
            }else if(ind instanceof TextIndice && mUITextIndices!=null)
            {
                TextView tv = new TextView(getActivity());
                tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
                tv.setText("  Indice "+(indInd+1)+" : "+((TextIndice) ind).getText());
                mUITextIndices.addView(tv);
            }
        }
        //si on arrive ici, ca veut dire que tous les indices ont ete découvert
        getDriver().setVisibilityView(R.id.btn_indice, View.INVISIBLE);
    }

    public Indice showIndice()
    {
        Indice ind = mChallenge.nextIndice();
        int indInd = mChallenge.getIndiceIndex();
        if(ind!=null)
        {
            if(getActivity() instanceof  ChallengeDriver)
            {
                if(ind instanceof GeoIndice)
                {
                    if(mUIGeoIndice!=null)
                    {
                        mUIGlobalIndice.setVisibility(View.VISIBLE);
                        mUIGeoIndice.setVisibility(View.VISIBLE);
                        startGeoUpdateTimer();
                        ind.discover();
                        return ind;
                    }
                    return null;
                }else if(ind instanceof TextIndice)
                {
                    if(mUITextIndices!=null)
                    {
                        mUIGlobalIndice.setVisibility(View.VISIBLE);
                        TextView tv = new TextView(getActivity());
                        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
                        tv.setText("  Indice "+(indInd+1)+" : "+((TextIndice) ind).getText());
                        mUITextIndices.addView(tv);
                        ind.discover();
                        return ind;
                    }
                }
            }
        }
        return null;
    }





    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container,int res) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(res, container, false);
        mUITextIndices= (LinearLayout) v.findViewById(R.id.ll_textIndices);
        mUIGeoIndice= (TextView) v.findViewById(R.id.tv_geoIndice);
        mUIGlobalIndice = (LinearLayout) v.findViewById(R.id.ll_rootIndices);
        return v;
    }


    public void initChallenge(Challenge c)
    {
        mChallenge=c;
        resetUi();
        if(!mChallenge.hasNextIndice())
        {
            getDriver().setVisibilityView(R.id.btn_indice, View.INVISIBLE);
        }
        onInitChallenge(c);
    }

    public ChallengeDriver getDriver()
    {
        Activity act = getActivity();
        if(act instanceof ChallengeDriver)
            return (ChallengeDriver)act;
        throw new RuntimeException("Error Activty hosting this Fragment ("+getClass()+") is not a ChallengeDriver");
    }


    protected void ready()
    {
        getDriver().onReady();
    }

    @Override
    public void onStart() {
        super.onStart();
        ready();
    }

    @Override
    public void onStop() {
        super.onStop();
        stopGeoUpdateTimer();
    }


    public void onResume() {
        super.onResume();
        updateIndices();
    }

    public void onPause() {
        super.onPause();
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return false;
    }

    private OnFragmentInteractionListener mListener;


    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }

    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public Challenge getChallenge() {
        return mChallenge;
    }



    //
    // Timer géolocalisation
    //

    protected void onGeoUpdateTimer()
    {
        IGeoTreasure gt = null;
        gt=(IGeoTreasure) mChallenge;

        Area a = gt.getArea();
        int d= (int)getDriver().getDistanceWith(a);
        if(d>=0) mUIGeoIndice.setText("Distance "+d+" m");
        else mUIGeoIndice.setText("Géolocalisation ...");
    }

    protected void stopGeoUpdateTimer()
    {
        if(mTimer!=null) mTimer.cancel();
    }

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

        }, 0, 1000);
    }

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


    //
    // Fin de Timer géolacalisation
    //


}
