// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.syncslides;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import io.v.syncslides.db.DB;
import io.v.syncslides.model.DynamicList;
import io.v.syncslides.model.ListListener;
import io.v.syncslides.model.Session;
import io.v.syncslides.model.Slide;
import io.v.v23.verror.VException;

/**
 * Provides both the presenter and audience views for navigating through a presentation.
 * Instantiated by the PresentationActivity along with other views/fragments of the presentation
 * to make transitions between them seamless.
 */
public class NavigateFragment extends Fragment {
    private static final String TAG = "NavigateFragment";
    private static final String SESSION_ID_KEY = "session_id_key";

    private Session mSession;
    private int mSlideNum = 0;
    private SlideNumberListener mSlideNumberListener = new SlideNumberListener();
    private ListListener mSlideListListener = new SlideListListener();
    private ImageView mPrevThumb;
    private ImageView mNextThumb;
    private ImageView mCurrentSlide;
    private TextView mSlideNumText;
    private EditText mNotes;
    private boolean mEditing;
    private DynamicList<Slide> mSlides;

    public static NavigateFragment newInstance(String sessionId) {
        NavigateFragment fragment = new NavigateFragment();
        Bundle args = new Bundle();
        args.putString(SESSION_ID_KEY, sessionId);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // When editing notes, display a menu with "Save".
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Bundle bundle = savedInstanceState;
        if (bundle == null) {
            bundle = getArguments();
        }
        String sessionId = bundle.getString(SESSION_ID_KEY);
        try {
            mSession = DB.Singleton.get().getSession(sessionId);
        } catch (VException e) {
            handleFatalError("Failed to fetch Session", e);
        }

        final View rootView = inflater.inflate(R.layout.fragment_navigate, container, false);

//        mFabSync = rootView.findViewById(R.id.audience_sync_fab);
//        if (((PresentationActivity) getActivity()).getSynced() || mRole != Role.AUDIENCE) {
//            mFabSync.setVisibility(View.INVISIBLE);
//        } else {
//            mFabSync.setVisibility(View.VISIBLE);
//        }
//
//        mFabSync.setOnClickListener(new NavigateClickListener() {
//            @Override
//            public void onClick(View v) {
//                super.onClick(v);
//                sync();
//                mFabSync.setVisibility(View.INVISIBLE);
//            }
//        });
        View.OnClickListener previousSlideListener = new NavigateClickListener() {
            @Override
            void onNavigate() {
                previousSlide();
            }
        };
        View arrowBack = rootView.findViewById(R.id.arrow_back);
        arrowBack.setOnClickListener(previousSlideListener);
        mPrevThumb = (ImageView) rootView.findViewById(R.id.prev_thumb);
        mPrevThumb.setOnClickListener(previousSlideListener);

        View.OnClickListener nextSlideListener = new NavigateClickListener() {
            @Override
            void onNavigate() {
                nextSlide();
            }
        };
        // Show either the arrowForward or the FAB but not both.
        View arrowForward = rootView.findViewById(R.id.arrow_forward);
        View fabForward = rootView.findViewById(R.id.primary_navigation_fab);
//        if (mRole == Role.PRESENTER) {
//            arrowForward.setVisibility(View.INVISIBLE);
//            fabForward.setOnClickListener(nextSlideListener);
//        } else {
        fabForward.setVisibility(View.INVISIBLE);
        arrowForward.setOnClickListener(nextSlideListener);
//        }
        mNextThumb = (ImageView) rootView.findViewById(R.id.next_thumb);
        mNextThumb.setOnClickListener(nextSlideListener);
//        mQuestions = (ImageView) rootView.findViewById(R.id.questions);
//        // TODO(kash): Hide the mQuestions button if mRole == BROWSER.
//        mQuestions.setOnClickListener(new NavigateClickListener() {
//            @Override
//            public void onClick(View v) {
//                super.onClick(v);
//                questionButton();
//            }
//        });
        mCurrentSlide = (ImageView) rootView.findViewById(R.id.slide_current_medium);
        mCurrentSlide.setOnClickListener(new NavigateClickListener() {
            @Override
            public void onNavigate() {
                // TODO(kash): Disallow presenter from switching to fullscreen.
                ((PresentationActivity) getActivity()).showFullscreenSlide();
            }
        });

        mSlideNumText = (TextView) rootView.findViewById(R.id.slide_num_text);
        mNotes = (EditText) rootView.findViewById(R.id.notes);
        mNotes.setOnFocusChangeListener((v, hasFocus) -> {
            if (hasFocus) {
                ((PresentationActivity) getActivity()).getSupportActionBar().show();
                mEditing = true;
                getActivity().invalidateOptionsMenu();
                // We don't want the presentation to advance while the user
                // is editing the notes.  Force the app to stay on this slide.
                try {
                    mSession.setLocalSlideNum(mSlideNum);
                } catch (VException e) {
                    handleFatalError("Could not set local slide num", e);
                }
            }
        });

        // The parent of mNotes needs to be focusable in order to clear focus
        // from mNotes when done editing.  We set the attributes in code rather
        // than in XML because it is too easy to add an extra level of layout
        // in XML and forget to add these attributes.
        ViewGroup parent = (ViewGroup) mNotes.getParent();
        parent.setFocusable(true);
        parent.setClickable(true);
        parent.setFocusableInTouchMode(true);

//        View slideListIcon = rootView.findViewById(R.id.slide_list);
//        slideListIcon.setOnClickListener(new NavigateClickListener() {
//            @Override
//            public void onClick(View v) {
//                super.onClick(v);
//                if (mRole == Role.AUDIENCE) {
//                    ((PresentationActivity) getActivity()).showSlideList();
//                } else {
//                    getActivity().getSupportFragmentManager().popBackStack();
//                }
//            }
//        });
//        mQuestionsNum = (TextView) rootView.findViewById(R.id.questions_num);
//        // Start off invisible for everyone.  If there are questions, this
//        // will be set to visible in the mDB.getQuestionerList() callback.
//        mQuestionsNum.setVisibility(View.INVISIBLE);
//
//        mDB = DB.Singleton.get(getActivity().getApplicationContext());
//        mDB.getSlides(mDeckId, new DB.Callback<List<Slide>>() {
//            @Override
//            public void done(List<Slide> slides) {
//                mSlides = slides;
//                // The CurrentSlideListener could have been notified while we were waiting for
//                // the slides to load.
//                if (mLoadingCurrentSlide != -1) {
//                    currentSlideChanged(mLoadingCurrentSlide);
//                }
//                updateView();
//            }
//        });
//        if (((PresentationActivity) getActivity()).getSynced()) {
//            sync();
//        } else {
//            unsync();
//        }

        return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();
        ((PresentationActivity) getActivity()).setUiImmersive(true);
        mSlides = mSession.getSlides();
        mSlides.addListener(mSlideListListener);
        mSession.addSlideNumberListener(mSlideNumberListener);
    }

    @Override
    public void onStop() {
        super.onStop();
        ((PresentationActivity) getActivity()).setUiImmersive(false);
        mSession.removeSlideNumberListener(mSlideNumberListener);
        mSlides.removeListener(mSlideListListener);
        mSlides = null;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(SESSION_ID_KEY, mSession.getId());
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (mEditing) {
            inflater.inflate(R.menu.edit_notes, menu);
        }
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_save:
                saveNotes();
                return true;
        }
        return false;
    }

    /**
     * Advances to the next slide, if there is one, and updates the UI.
     */
    private void nextSlide() {
        if (mSlideNum == -1) {
            // Wait until the state has loaded before letting the user move around.
            return;
        }
        if (mSlideNum < mSession.getSlides().getItemCount() - 1) {
            try {
                mSession.setLocalSlideNum(mSlideNum + 1);
            } catch (VException e) {
                handleError("Failed to advance", e);
            }
        }
    }

    /**
     * Goes back to the previous slide, if there is one, and updates the UI.
     */
    private void previousSlide() {
        if (mSlideNum == -1) {
            // Wait until the state has loaded before letting the user move around.
            return;
        }
        if (mSlideNum > 0) {
            try {
                mSession.setLocalSlideNum(mSlideNum - 1);
            } catch (VException e) {
                handleError("Failed to go back", e);
            }
        }
    }

    private void updateView() {
        if (mSlideNum < 0 || mSlideNum >= mSlides.getItemCount()) {
            // Still loading.
            return;
        }
        if (mSlideNum > 0) {
            setThumbBitmap(mPrevThumb, mSlides.get(mSlideNum - 1).getThumb());
        } else {
            setThumbNull(mPrevThumb);
        }
        // TODO(kash): Switch to full size image.
        mCurrentSlide.setImageBitmap(mSlides.get(mSlideNum).getThumb());
        if (mSlideNum == mSlides.getItemCount() - 1) {
            setThumbNull(mNextThumb);
        } else {
            setThumbBitmap(mNextThumb, mSlides.get(mSlideNum + 1).getThumb());
        }
        if (!mSlides.get(mSlideNum).getNotes().equals("")) {
            mNotes.setText(mSlides.get(mSlideNum).getNotes());
        } else {
            mNotes.getText().clear();
        }
        mSlideNumText.setText(
                String.valueOf(mSlideNum + 1) + " of " + String.valueOf(mSlides.getItemCount()));
    }

    private void setThumbBitmap(ImageView thumb, Bitmap bitmap) {
        thumb.setImageBitmap(bitmap);
        // In landscape, the height is dependent on the image size.  However, if the
        // image was null, the height is hardcoded to 9/16 of the width in setThumbNull.
        // This resets it to the actual image size.
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            ViewGroup.LayoutParams thumbParams = thumb.getLayoutParams();
            thumbParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        }
    }

    private void setThumbNull(ImageView thumb) {
        thumb.setImageDrawable(null);
        // In landscape, the height is dependent on the image size.  Because we don't have an
        // image, assume all of the images are 16:9.  The width is fixed, so we can calculate
        // the expected height.
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            ViewGroup grandparent = (ViewGroup) thumb.getParent().getParent();
            ViewGroup.LayoutParams thumbParams = thumb.getLayoutParams();
            thumbParams.height = (int) ((9 / 16.0) * grandparent.getMeasuredWidth());
        }
    }

    /**
     * If the user is editing the text field and the text has changed, save the
     * notes in Syncbase.  That will trigger a notification that the slide has
     * changed and the UI will refresh.
     */
    public void saveNotes() {
        final String notes = mNotes.getText().toString();
        if (mEditing && (!notes.equals(mSlides.get(mSlideNum).getNotes()))) {
            try {
                mSession.setNotes(mSlideNum, notes);
            } catch (VException e) {
                handleError("Could not save notes", e);
            }
        }
        mNotes.clearFocus();
        mEditing = false;
        InputMethodManager inputManager =
                (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (getActivity().getCurrentFocus() != null) {
            inputManager.hideSoftInputFromWindow(
                    getActivity().getCurrentFocus().getWindowToken(),
                    InputMethodManager.HIDE_NOT_ALWAYS);
        }
        ((PresentationActivity) getActivity()).setUiImmersive(true);
    }

    private void handleError(String msg, Throwable throwable) {
        Log.e(TAG, msg + ": " + Log.getStackTraceString(throwable));
        Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
    }

    private void handleFatalError(String msg, Throwable throwable) {
        handleError(msg, throwable);
        getActivity().finish();
    }

    /**
     * Updates the view whenever the list of slides changes.
     */
    private class SlideListListener implements ListListener {
        @Override
        public void notifyDataSetChanged() {
            updateView();
        }

        @Override
        public void notifyItemChanged(int position) {
            updateView();
        }

        @Override
        public void notifyItemInserted(int position) {
            updateView();
        }

        @Override
        public void notifyItemRemoved(int position) {
            updateView();
        }

        @Override
        public void onError(Exception e) {
            handleFatalError("Error watching slide list", e);
        }
    }

    private class SlideNumberListener implements Session.SlideNumberListener {
        @Override
        public void onChange(int slideNum) {
            mSlideNum = slideNum;
            updateView();
        }

        @Override
        public void onError(Exception e) {
            handleFatalError("Error listening to slide number changes", e);
        }
    }

    /**
     * If the user is editing notes and then clicks anywhere else on the screen,
     * we want that action to save the notes first.  Using this class forces
     * that behavior.
     */
    private abstract class NavigateClickListener implements View.OnClickListener {
        @Override
        public final void onClick(View v) {
            saveNotes();
            onNavigate();
        }

        /**
         * Called when there is a click.
         */
        abstract void onNavigate();
    }
}
