// 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.android.apps.syncslides;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.view.Gravity;
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.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

import io.v.android.apps.syncslides.db.DB;
import io.v.android.apps.syncslides.model.Question;
import io.v.android.apps.syncslides.model.Role;
import io.v.android.apps.syncslides.model.Slide;

/**
 * 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 DECK_ID_KEY = "deck_id_key";
    private static final String PRESENTATION_ID_KEY = "presentation_id_key";
    private static final String SLIDE_NUM_KEY = "slide_num_key";
    private static final String ROLE_KEY = "role_key";
    private static final int DIALOG_REQUEST_CODE = 23;

    // TODO(afergan): Move state variables to activity.
    private String mDeckId;
    private String mPresentationId;
    /**
     * The slide number for the live presentation, if any.
     */
    private int mCurrentSlideNum;
    /**
     * While mSlides is loading, we can't validate any slide numbers coming from DB.
     * We hold them here until mSlides finishes loading.
     */
    private int mLoadingCurrentSlide;
    /**
     * The slide number that the user is viewing.  This will be different from mCurrentSlideNum
     * if mRole == AUDIENCE and the user went forwards or backwards in the deck.
     */
    private int mUserSlideNum;
    private ImageView mPrevThumb;
    private ImageView mNextThumb;
    private ImageView mCurrentSlide;
    private ImageView mQuestions;
    private View mFabSync;
    private TextView mQuestionsNum;
    private EditText mNotes;
    private List<Slide> mSlides;
    private Role mRole;
    private List<Question> mQuestionList;
    private DB.QuestionListener mQuestionListener;
    private boolean mEditing;
    private int mQuestionerPosition;
    private boolean mSynced;
    private DB.CurrentSlideListener mCurrentSlideListener;
    private DB mDB;
    private TextView mSlideNumText;

    public static NavigateFragment newInstance(
            String deckId, String presentationId, int slideNum, Role role) {
        NavigateFragment fragment = new NavigateFragment();
        Bundle args = new Bundle();
        args.putString(DECK_ID_KEY, deckId);
        args.putString(PRESENTATION_ID_KEY, presentationId);
        args.putInt(SLIDE_NUM_KEY, slideNum);
        args.putSerializable(ROLE_KEY, role);
        fragment.setArguments(args);
        return fragment;
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Bundle args;
        if (savedInstanceState != null) {
            args = savedInstanceState;
        } else {
            args = getArguments();
        }
        mDeckId = args.getString(DECK_ID_KEY);
        mPresentationId = args.getString(PRESENTATION_ID_KEY);
        mLoadingCurrentSlide = -1;
        mUserSlideNum = args.getInt(SLIDE_NUM_KEY);
        mRole = (Role) args.get(ROLE_KEY);
        if (((PresentationActivity) getActivity()).getSynced()) {
            sync();
        } else {
            unsync();
        }
        final View rootView = inflater.inflate(R.layout.fragment_navigate, container, false);
        mFabSync = rootView.findViewById(R.id.audience_sync_fab);
        if (mSynced || 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
            public void onClick(View v) {
                super.onClick(v);
                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
            public void onClick(View v) {
                super.onClick(v);
                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 onClick(View v) {
                super.onClick(v);
                if (mRole == Role.AUDIENCE || mRole == Role.BROWSER) {
                    ((PresentationActivity) getActivity()).showFullscreenSlide(mUserSlideNum);
                }
            }
        });

        mSlideNumText = (TextView) rootView.findViewById(R.id.slide_num_text);
        mNotes = (EditText) rootView.findViewById(R.id.notes);
        mNotes.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                ((PresentationActivity) getActivity()).getSupportActionBar().show();
                mEditing = hasFocus;
                getActivity().invalidateOptionsMenu();
                unsync();
            }
        });

        // 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);
                } else {
                    updateView();
                }
            }
        });

        return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();
        ((PresentationActivity) getActivity()).setUiImmersive(true);
        if (mRole == Role.AUDIENCE) {
            mCurrentSlideListener = new DB.CurrentSlideListener() {
                @Override
                public void onChange(int slideNum) {
                    NavigateFragment.this.currentSlideChanged(slideNum);
                }
            };
            mDB.addCurrentSlideListener(mDeckId, mPresentationId, mCurrentSlideListener);
        }
        if (mRole == Role.PRESENTER) {
            mQuestionListener = new DB.QuestionListener() {
                @Override
                public void onChange(List<Question> questions) {
                    mQuestionList = questions;
                    if (mQuestionList.size() > 0) {
                        mQuestionsNum.setVisibility(View.VISIBLE);
                        mQuestionsNum.setText(String.valueOf(mQuestionList.size()));
                    } else {
                        mQuestionsNum.setVisibility(View.INVISIBLE);
                    }
                }
            };
            mDB.setQuestionListener(mDeckId, mPresentationId, mQuestionListener);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        ((PresentationActivity) getActivity()).setUiImmersive(false);
        if (mRole == Role.AUDIENCE) {
            mDB.removeCurrentSlideListener(mDeckId, mPresentationId, mCurrentSlideListener);
        }
        if (mRole == Role.PRESENTER) {
            mDB.removeQuestionListener(mDeckId, mPresentationId, mQuestionListener);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(DECK_ID_KEY, mDeckId);
        outState.putString(PRESENTATION_ID_KEY, mPresentationId);
        outState.putInt(SLIDE_NUM_KEY, mUserSlideNum);
        outState.putSerializable(ROLE_KEY, mRole);
    }

    @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;
    }

    public void saveNotes() {
        if (mEditing) {
            Toast.makeText(getContext(), "Saving notes", Toast.LENGTH_SHORT).show();
            mNotes.clearFocus();
            InputMethodManager inputManager =
                    (InputMethodManager) getContext().
                            getSystemService(Context.INPUT_METHOD_SERVICE);
            inputManager.hideSoftInputFromWindow(
                    getActivity().getCurrentFocus().getWindowToken(),
                    InputMethodManager.HIDE_NOT_ALWAYS);
            ((PresentationActivity) getActivity()).setUiImmersive(true);
        }
    }

    private void unsync() {
        if (mRole == Role.AUDIENCE && mSynced) {
            mSynced = false;
            ((PresentationActivity) getActivity()).setUnsynced();
            mFabSync.setVisibility(View.VISIBLE);
        }
    }

    private void sync() {
        mSynced = true;
        mUserSlideNum = mCurrentSlideNum;
        ((PresentationActivity) getActivity()).setSynced();
        updateView();
    }

    /**
     * Advances to the next slide, if there is one, and updates the UI.
     */
    private void nextSlide() {
        if (mSlides == null) {
            // Wait until the slides have loaded before letting the user move around.
            return;
        }
        if (mUserSlideNum < mSlides.size() - 1) {
            mUserSlideNum++;
            if (mRole == Role.PRESENTER) {
                mDB.setCurrentSlide(mDeckId, mPresentationId, mUserSlideNum);
            }
            updateView();
            unsync();
        }
    }

    /**
     * Goes back to the previous slide, if there is one, and updates the UI.
     */
    private void previousSlide() {
        if (mSlides == null) {
            // Wait until the slides have loaded before letting the user move around.
            return;
        }
        if (mUserSlideNum > 0) {
            mUserSlideNum--;
            if (mRole == Role.PRESENTER) {
                mDB.setCurrentSlide(mDeckId, mPresentationId, mUserSlideNum);
            }
            updateView();
            unsync();
        }
    }

    private void currentSlideChanged(int slideNum) {
        if (mSlides == null) {
            // We can't validate that slideNum is within the bounds of mSlides.  Hold it off
            // to the side until mSlides finishes loading.
            mLoadingCurrentSlide = slideNum;
            return;
        }
        if (slideNum < 0 || slideNum >= mSlides.size()) {
            return;
        }
        mCurrentSlideNum = slideNum;
        if (mSynced) {
            mUserSlideNum = slideNum;
            updateView();
        }
    }

    /**
     * When the user presses the icon, add the user's identity to the presenter's question queue.
     * If presenter presses the button, get a list of users who are asking questions.
     */
    private void questionButton() {
        DB db = DB.Singleton.get(getActivity().getApplicationContext());
        switch (mRole) {
            case AUDIENCE:
                db.askQuestion(mDeckId, mPresentationId, "Audience member", "#1");
                Toast toast = Toast.makeText(getActivity().getApplicationContext(),
                        "You have been added to the Q&A queue.", Toast.LENGTH_LONG);
                toast.show();
                break;
            case PRESENTER:
                if (mQuestionList == null || mQuestionList.size() == 0) {
                    break;
                }
                // TODO(kash): It would be better to pass the entire Question to the dialog.
                String[] questioners = new String[mQuestionList.size()];
                for (int i = 0; i < mQuestionList.size(); i++) {
                    questioners[i] = mQuestionList.get(i).getFirstName() + " "
                            + mQuestionList.get(i).getLastName();
                }
                DialogFragment dialog = QuestionDialogFragment.newInstance(questioners);
                dialog.setTargetFragment(this, DIALOG_REQUEST_CODE);
                dialog.show(getFragmentManager(), "QuestionerDialogFragment");
                break;
            case BROWSER:
                // Do nothing.
                break;
        }
    }

    private void updateView() {
        if (mSlides == null) {
            // We can't do anything until the slides have loaded.
            return;
        }
        if (mUserSlideNum > 0) {
            setThumbBitmap(mPrevThumb, mSlides.get(mUserSlideNum - 1).getImage());
        } else {
            setThumbNull(mPrevThumb);
        }
        mCurrentSlide.setImageBitmap(mSlides.get(mUserSlideNum).getImage());
        if (mUserSlideNum == mSlides.size() - 1) {
            setThumbNull(mNextThumb);
        } else {
            setThumbBitmap(mNextThumb, mSlides.get(mUserSlideNum + 1).getImage());
        }
        if (!mSlides.get(mUserSlideNum).getNotes().equals("")) {
            mNotes.setText(mSlides.get(mUserSlideNum).getNotes());
        } else {
            mNotes.getText().clear();
        }
        mSlideNumText.setText(
                String.valueOf(mUserSlideNum + 1) + " of " + String.valueOf(mSlides.size()));
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == DIALOG_REQUEST_CODE) {
            // TODO(afergan): Using the position is insufficient if the list of questioners changes
            // while the dialog is showing.
            mQuestionerPosition = data.getIntExtra(
                    QuestionDialogFragment.QUESTION_BUNDLE_KEY, 0);
            handoffControl();
        }
    }

    /**
     * Handoff control of the presentation to a questioner. A snackbar displays the status while
     * the audience member is in control, and control ends when the presenter presses the action
     * text.
     */
    private void handoffControl() {
        //TODO(afergan): Change slide presenter to the audience member at mQuestionerPosition.
        View.OnClickListener snackbarClickListener = new NavigateClickListener() {
            @Override
            public void onClick(View v) {
                super.onClick(v);
                //TODO(afergan): End handoff, presenter regains control of presentation.
            }
        };

        ((PresentationActivity) getActivity()).setUiImmersive(true);
        Snackbar snack = Snackbar.make(getView(), getResources().getString(
                        R.string.handoff_message) + " "
                        + mQuestionList.get(mQuestionerPosition).getFirstName() + " "
                        + mQuestionList.get(mQuestionerPosition).getLastName(),
                Snackbar.LENGTH_INDEFINITE)
                .setAction(getResources().getString(R.string.end_handoff),
                        snackbarClickListener)
                .setActionTextColor(ContextCompat.getColor(getContext(), R.color.action_orange));

        // Needed to set the location of the snackbar (default is bottom center, which hides buttons
        // in landscape mode).
        View view = snack.getView();
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams();
        params.gravity = Gravity.RIGHT | Gravity.BOTTOM;
        view.setLayoutParams(params);
        snack.show();
    }

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

    public class NavigateClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            saveNotes();
        }
    }
}