package app.mar.activities;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.textclassifier.TextClassifier;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

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

import app.mar.game.Area;
import app.mar.game.Resource;
import app.mar.game.ResourceManager;
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;
import app.mar.utils.files.FileManager;
import uk.co.senab.photoview.PhotoViewAttacher;

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



    protected LinearLayout  mUITextIndices;
    protected TextView      mUIGeoIndice;
    protected LinearLayout  mUIGlobalIndice;
    protected Challenge     mChallenge;
    protected ImageView     mImage;
    private PhotoViewAttacher mAttacher;

    protected Timer         mTimer;

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


    protected void onInitChallenge(Challenge c)
    {
        if(c!=null) setImageResource(c.getResourceName());
    }

    public boolean onBackPressed()
    {
        stopGeoUpdateTimer();
        return true;
    }

    protected void setImageResource(String res)
    {
        Resource r = ResourceManager.getInstance().get(res);

        if(r!=null && r.isImage() )
        {
            String name = r.getName();
            Bitmap bmp=null;
            try {
                bmp = FileManager.openImage(getActivity(), name);
            } catch (Exception e) {
                e.printStackTrace();
                Toast.makeText(getActivity(), "Impossible de charger '"+name+"'", Toast.LENGTH_LONG).show();
            }

            mImage.setImageBitmap(bmp);
            mAttacher = new PhotoViewAttacher(mImage);
            mAttacher.setMaximumScale(20);
        }
        else
        {

        }
    }

    public void resetUi()
    {
        getDriver().setVisibilityView(R.id.btn_indice, View.VISIBLE);
        if(mUIGeoIndice!=null)
        {
            mUIGeoIndice.setVisibility(View.GONE);
        }
        if(mUITextIndices!=null)
        {
            mUITextIndices.removeAllViews();
        }
        if(mUIGlobalIndice!=null)
        {
            mUIGlobalIndice.setVisibility(View.GONE);
        }
        onResetUi();
    }

    protected TextView createTextView(Indice ind, int indInd)
    {
        TextView tv = new TextView(getActivity());
        tv.setTextColor(0xff70e030);
        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
        tv.setText("  Indice "+(indInd+1)+" : "+((TextIndice) ind).getText());
        tv.setTypeface(null, Typeface.BOLD);
        return  tv;
    }

    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)
            {
                mUITextIndices.addView(createTextView(ind, indInd));
            }
        }
        //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);
                        mUITextIndices.addView(createTextView(ind, indInd));
                        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);
        mImage = (ImageView) v.findViewById(R.id.iv_img);
        return v;
    }


    public void initChallenge(Challenge c)
    {
        if(c==null)
        {
            getDriver().setFinished();
        }
        mChallenge=c;
        resetUi();
        if(mChallenge!=null && !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;
        else if(act==null)
            return null;
        throw new RuntimeException("Error Activty hosting this Fragment ("+getClass()+") is not a ChallengeDriver");
    }




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

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

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


    public void onResume() {
        super.onResume();
        if(mChallenge!=null) updateIndices();
    }

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

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

    private OnFragmentInteractionListener mListener;


    public interface OnFragmentInteractionListener {
        void onFragmentInteraction(Uri uri);
    }

    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();

        ChallengeDriver cd = getDriver();

        if(cd==null)
        {
            stopGeoUpdateTimer();
        }else
        {
            int d=(int) cd.getDistanceWith(a);
            int accuracy = -1;
            try{
                accuracy = (int) cd.getAccuracy();
            }catch(Exception e)
            {
            }
            if(d>=0 && accuracy>=0) mUIGeoIndice.setText("Distance "+d+" m  (+/- "+accuracy+" m)");
            else mUIGeoIndice.setText("Géolocalisation en cours ...");

        }

    }

    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()
    {
        Activity a = getActivity();
        if(a!=null) a.runOnUiThread(mTimerTick);
        else stopGeoUpdateTimer();
    }


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


}
