// 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.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.provider.DocumentFile;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Toast;

import com.google.common.base.Charsets;
import com.google.common.io.ByteStreams;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.UUID;

import io.v.android.apps.syncslides.db.DB;
import io.v.android.apps.syncslides.model.Deck;
import io.v.android.apps.syncslides.model.DeckFactory;
import io.v.android.apps.syncslides.model.Slide;
import io.v.android.apps.syncslides.model.SlideImpl;

/**
 * This fragment contains the list of decks as well as the FAB to create a new
 * deck.
 */
public class DeckChooserFragment extends Fragment {
    /**
     * The fragment argument representing the section number for this fragment.
     */
    private static final String ARG_SECTION_NUMBER = "section_number";
    private static final String TAG = "DeckChooserFragment";
    private static final int REQUEST_CODE_IMPORT_DECK = 1000;
    private RecyclerView mRecyclerView;
    private GridLayoutManager mLayoutManager;
    private DeckListAdapter mAdapter;

    /**
     * Returns a new instance of this fragment for the given section number.
     */
    public static DeckChooserFragment newInstance(int sectionNumber) {
        DeckChooserFragment fragment = new DeckChooserFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_deck_chooser, container, false);
        FloatingActionButton fab = (FloatingActionButton) rootView.findViewById(R.id.new_deck_fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onImportDeck();
            }
        });
        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.deck_grid);
        mRecyclerView.setHasFixedSize(true);

        // Statically set the span count (i.e. number of columns) for now...  See below.
        mLayoutManager = new GridLayoutManager(getContext(), 2);
        mRecyclerView.setLayoutManager(mLayoutManager);
        // Dynamically set the span based on the screen width.  Cribbed from
        // http://stackoverflow.com/questions/26666143/recyclerview-gridlayoutmanager-how-to-auto-detect-span-count
        mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        int viewWidth = mRecyclerView.getMeasuredWidth();
                        float cardViewWidth = getActivity().getResources().getDimension(
                                R.dimen.deck_card_width);
                        int newSpanCount = (int) Math.floor(viewWidth / cardViewWidth);
                        mLayoutManager.setSpanCount(newSpanCount);
                        mLayoutManager.requestLayout();
                    }
                });

        return rootView;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQUEST_CODE_IMPORT_DECK:
                if (resultCode != Activity.RESULT_OK) {
                    String errorStr = data != null && data.hasExtra(DocumentsContract.EXTRA_ERROR)
                            ? data.getStringExtra(DocumentsContract.EXTRA_ERROR)
                            : "";
                    toast("Error selecting deck to import " + errorStr);
                    break;
                }
                Uri uri = data.getData();
                importDeck(DocumentFile.fromTreeUri(getContext(), uri));
                break;
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        ((DeckChooserActivity) activity).onSectionAttached(
                getArguments().getInt(ARG_SECTION_NUMBER));
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.i(TAG, "Starting");
        DB db = DB.Singleton.get(getActivity().getApplicationContext());
        mAdapter = new DeckListAdapter(db);
        mAdapter.start(getActivity().getApplicationContext());
        mRecyclerView.setAdapter(mAdapter);
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.i(TAG, "Stopping");
        mAdapter.stop();
        mAdapter = null;
    }

    /**
     * Import a deck so it shows up in the list of all decks.
     */
    private void onImportDeck() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        startActivityForResult(intent, REQUEST_CODE_IMPORT_DECK);
    }

    /**
     * Import a slide deck from the given (local) folder.
     *
     * The folder must contain a JSON metadata file 'deck.json' with the following format:
     * {
     *     "Title" : "<title>",
     *     "Thumb" : "<filename>,
     *     "Slides" : [
     *          {
     *              "Thumb" : "<filename1>",
     *              "Note" : "<note1>"
     *          },
     *          {
     *              "Thumb" : "<filename2>",
     *              "Note" : "<note2>"
     *          },
     *
     *          ...
     *     ]
     * }
     *
     * All the filenames must be local to the given folder.
     */
    private void importDeck(DocumentFile dir) {
        if (!dir.isDirectory()) {
            toast("Must import from a directory, got: " + dir);
            return;
        }
        // Read the deck metadata file.
        DocumentFile metadataFile = dir.findFile("deck.json");
        if (metadataFile == null) {
            toast("Couldn't find deck metadata file 'deck.json'");
            return;
        }
        JSONObject metadata = null;
        try {
            String data = new String(ByteStreams.toByteArray(
                    getActivity().getContentResolver().openInputStream(metadataFile.getUri())),
                    Charsets.UTF_8);
            metadata = new JSONObject(data);
        } catch (FileNotFoundException e) {
            toast("Couldn't open deck metadata file: " + e.getMessage());
            return;
        } catch (IOException e) {
            toast("Couldn't read data from deck metadata file: " + e.getMessage());
            return;
        } catch (JSONException e) {
            toast("Couldn't parse deck metadata: " + e.getMessage());
            return;
        }

        try {
            String id = UUID.randomUUID().toString();
            String title = metadata.getString("Title");
            Bitmap thumb = readImage(dir, metadata.getString("Thumb"));
            Deck deck = DeckFactory.Singleton.get().make(title, thumb, id);
            Slide[] slides = readSlides(dir, metadata);
            // TODO(spetrovic): Do this asynchronously.
            DB.Singleton.get(getActivity().getApplicationContext()).importDeck(deck, slides);
        } catch (JSONException e) {
            toast("Invalid format for deck metadata: " + e.getMessage());
            return;
        } catch (IOException e) {
            toast("Error interpreting deck metadata: " + e.getMessage());
            return;
        }
    }

    private Slide[] readSlides(DocumentFile dir, JSONObject metadata)
            throws JSONException, IOException {
        if (!metadata.has("Slides")) {
            return new Slide[0];
        }
        JSONArray slides = metadata.getJSONArray("Slides");
        Slide[] ret = new Slide[slides.length()];
        for (int i = 0; i < slides.length(); ++i) {
            JSONObject slide = slides.getJSONObject(i);
            Bitmap thumb = readImage(dir, slide.getString("Thumb"));
            String note = slide.getString("Note");
            ret[i] = new SlideImpl(thumb, note);
        }
        return ret;
    }

    private Bitmap readImage(DocumentFile dir, String fileName) throws IOException {
        DocumentFile file = dir.findFile(fileName);
        if (file == null) {
            throw new FileNotFoundException(
                    "Thumbnail file doesn't exist: " + fileName);
        }
        return MediaStore.Images.Media.getBitmap(
                getActivity().getContentResolver(), file.getUri());
    }

    private void toast(String msg) {
        Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
    }
}
