/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.android.directoryselection;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * Fragment that demonstrates how to use Directory Selection API.
 */
public class DirectorySelectionFragment extends Fragment {

    private static final String TAG = DirectorySelectionFragment.class.getSimpleName();

    public static final int REQUEST_CODE_OPEN_DIRECTORY = 1;

    Uri mCurrentDirectoryUri;
    TextView mCurrentDirectoryTextView;
    Button mCreateDirectoryButton;
    RecyclerView mRecyclerView;
    DirectoryEntryAdapter mAdapter;
    RecyclerView.LayoutManager mLayoutManager;

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment {@link DirectorySelectionFragment}.
     */
    public static DirectorySelectionFragment newInstance() {
        DirectorySelectionFragment fragment = new DirectorySelectionFragment();
        return fragment;
    }

    public DirectorySelectionFragment() {
        // Required empty public constructor
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_directory_selection, container, false);
    }

    @Override
    public void onViewCreated(View rootView, Bundle savedInstanceState) {
        super.onViewCreated(rootView, savedInstanceState);

        rootView.findViewById(R.id.button_open_directory)
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
                        startActivityForResult(intent, REQUEST_CODE_OPEN_DIRECTORY);
                    }
                });

        mCurrentDirectoryTextView = (TextView) rootView
                .findViewById(R.id.textview_current_directory);
        mCreateDirectoryButton = (Button) rootView.findViewById(R.id.button_create_directory);
        mCreateDirectoryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final EditText editView = new EditText(getActivity());
                new AlertDialog.Builder(getActivity())
                        .setTitle(R.string.create_directory)
                        .setView(editView)
                        .setPositiveButton(android.R.string.ok,
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        createDirectory(mCurrentDirectoryUri,
                                                editView.getText().toString());
                                        updateDirectoryEntries(mCurrentDirectoryUri);
                                    }
                                })
                        .setNegativeButton(android.R.string.cancel,
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                    }
                                })
                        .show();
            }
        });
        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview_directory_entries);
        mLayoutManager = mRecyclerView.getLayoutManager();
        mRecyclerView.scrollToPosition(0);
        mAdapter = new DirectoryEntryAdapter(new ArrayList<DirectoryEntry>());
        mRecyclerView.setAdapter(mAdapter);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_OPEN_DIRECTORY && resultCode == Activity.RESULT_OK) {
            Log.d(TAG, String.format("Open Directory result Uri : %s", data.getData()));
            updateDirectoryEntries(data.getData());
            mAdapter.notifyDataSetChanged();
        }
    }


    /**
     * Updates the current directory of the uri passed as an argument and its children directories.
     * And updates the {@link #mRecyclerView} depending on the contents of the children.
     *
     * @param uri The uri of the current directory.
     */
    //VisibileForTesting
    void updateDirectoryEntries(Uri uri) {
        ContentResolver contentResolver = getActivity().getContentResolver();
        Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
                DocumentsContract.getTreeDocumentId(uri));
        Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri,
                DocumentsContract.getTreeDocumentId(uri));

        Cursor docCursor = contentResolver.query(docUri, new String[]{
                Document.COLUMN_DISPLAY_NAME, Document.COLUMN_MIME_TYPE}, null, null, null);
        try {
            while (docCursor.moveToNext()) {
                Log.d(TAG, "found doc =" + docCursor.getString(0) + ", mime=" + docCursor
                        .getString(1));
                mCurrentDirectoryUri = uri;
                mCurrentDirectoryTextView.setText(docCursor.getString(0));
                mCreateDirectoryButton.setEnabled(true);
            }
        } finally {
            closeQuietly(docCursor);
        }

        Cursor childCursor = contentResolver.query(childrenUri, new String[]{
                Document.COLUMN_DISPLAY_NAME, Document.COLUMN_MIME_TYPE}, null, null, null);
        try {
            List<DirectoryEntry> directoryEntries = new ArrayList<>();
            while (childCursor.moveToNext()) {
                Log.d(TAG, "found child=" + childCursor.getString(0) + ", mime=" + childCursor
                        .getString(1));
                DirectoryEntry entry = new DirectoryEntry();
                entry.fileName = childCursor.getString(0);
                entry.mimeType = childCursor.getString(1);
                directoryEntries.add(entry);
            }
            mAdapter.setDirectoryEntries(directoryEntries);
            mAdapter.notifyDataSetChanged();
        } finally {
            closeQuietly(childCursor);
        }
    }

    /**
     * Creates a directory under the directory represented as the uri in the argument.
     *
     * @param uri The uri of the directory under which a new directory is created.
     * @param directoryName The directory name of a new directory.
     */
    //VisibileForTesting
    void createDirectory(Uri uri, String directoryName) {
        ContentResolver contentResolver = getActivity().getContentResolver();
        Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
                DocumentsContract.getTreeDocumentId(uri));
        Uri directoryUri = DocumentsContract
                .createDocument(contentResolver, docUri, Document.MIME_TYPE_DIR, directoryName);
        if (directoryUri != null) {
            Log.i(TAG, String.format(
                    "Created directory : %s, Document Uri : %s, Created directory Uri : %s",
                    directoryName, docUri, directoryUri));
            Toast.makeText(getActivity(), String.format("Created a directory [%s]",
                    directoryName), Toast.LENGTH_SHORT).show();
        } else {
            Log.w(TAG, String.format("Failed to create a directory : %s, Uri %s", directoryName,
                    docUri));
            Toast.makeText(getActivity(), String.format("Failed to created a directory [%s] : ",
                    directoryName), Toast.LENGTH_SHORT).show();
        }

    }

    public void closeQuietly(AutoCloseable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (RuntimeException rethrown) {
                throw rethrown;
            } catch (Exception ignored) {
            }
        }
    }
}

