package com.mercandalli.android.apps.files.file.image;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.DrawableRes;
import android.support.annotation.IntDef;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.mercandalli.android.apps.files.R;
import com.mercandalli.android.apps.files.common.animation.ScaleAnimationAdapter;
import com.mercandalli.android.apps.files.common.fragment.BackFragment;
import com.mercandalli.android.apps.files.common.listener.IListener;
import com.mercandalli.android.apps.files.common.listener.IPostExecuteListener;
import com.mercandalli.android.apps.files.common.net.TaskPost;
import com.mercandalli.android.apps.files.common.util.StringPair;
import com.mercandalli.android.apps.files.file.FileManager;
import com.mercandalli.android.apps.files.file.FileModel;
import com.mercandalli.android.apps.files.file.FileModelCardAdapter;
import com.mercandalli.android.apps.files.file.FileModelCardHeaderItem;
import com.mercandalli.android.apps.files.file.FileModelListener;
import com.mercandalli.android.apps.files.file.audio.FileAudioModel;
import com.mercandalli.android.apps.files.file.local.FileLocalPagerFragment;
import com.mercandalli.android.apps.files.file.local.fab.FileLocalFabManager;
import com.mercandalli.android.apps.files.main.Config;
import com.mercandalli.android.apps.files.main.Constants;
import com.mercandalli.android.library.base.dialog.DialogUtils;
import com.mercandalli.android.library.base.java.StringUtils;
import org.json.JSONObject;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
/**
* A {@link android.support.v4.app.Fragment} that displays the local {@link FileAudioModel}s.
*/
public class FileImageLocalFragment extends BackFragment implements
FileModelCardAdapter.OnFileSubtitleAdapter,
FileModelCardAdapter.OnHeaderClickListener,
FileImageManager.GetAllLocalImageListener,
FileImageManager.GetLocalImageFoldersListener,
FileImageManager.GetLocalImageListener,
FileLocalPagerFragment.ListController,
ScaleAnimationAdapter.NoAnimatedPosition,
SwipeRefreshLayout.OnRefreshListener,
FileLocalPagerFragment.ScrollTop,
FileLocalFabManager.FabController {
/**
* A key for the view pager position.
*/
private static final String ARG_POSITION_IN_VIEW_PAGER = "FileLocalFragment.Args.ARG_POSITION_IN_VIEW_PAGER";
@Retention(RetentionPolicy.SOURCE)
@IntDef({
PAGE_FOLDERS,
PAGE_FOLDER_INSIDE,
PAGE_ALL})
public @interface CurrentPage {
}
private static final int PAGE_FOLDERS = 0;
private static final int PAGE_FOLDER_INSIDE = 1;
private static final int PAGE_ALL = 2;
@CurrentPage
private int mCurrentPage = PAGE_FOLDERS;
private RecyclerView mRecyclerView;
private List<FileModel> mFileModels;
private TextView mMessageTextView;
private String mStringDirectory;
private String mStringImage;
private String mStringImages;
private List<FileModelCardHeaderItem> mHeaderIds;
/**
* A simple {@link ProgressBar}. Call {@link #showProgressBar()} or {@link #hideProgressBar()}.
*/
private ProgressBar mProgressBar;
private FileImageAdapter mFileImageAdapter;
private FileModelCardAdapter mFileModelCardAdapter;
private final IListener mRefreshActivityAdapterListener;
private ScaleAnimationAdapter mScaleAnimationAdapter;
private SwipeRefreshLayout mSwipeRefreshLayout;
/**
* A simple {@link Handler}. Called by {@link #showProgressBar()} or {@link #hideProgressBar()}.
*/
private final Handler mProgressBarActivationHandler;
/**
* A simple {@link Runnable}. Called by {@link #showProgressBar()} or {@link #hideProgressBar()}.
*/
private final Runnable mProgressBarActivationRunnable;
private FileModel mCurrentFolder;
private int mPositionInViewPager;
private FileLocalFabManager mFileLocalFabManager;
private FileManager mFileManager;
private FileImageManager mFileImageManager;
public static FileImageLocalFragment newInstance(final int positionInViewPager) {
final FileImageLocalFragment fileAudioLocalFragment = new FileImageLocalFragment();
final Bundle args = new Bundle();
args.putInt(ARG_POSITION_IN_VIEW_PAGER, positionInViewPager);
fileAudioLocalFragment.setArguments(args);
return fileAudioLocalFragment;
}
/**
* Do not use this constructor. Call {@link #newInstance(int)} instead.
*/
public FileImageLocalFragment() {
mRefreshActivityAdapterListener = new IListener() {
@Override
public void execute() {
refreshCurrentList();
}
};
mProgressBarActivationHandler = new Handler();
mProgressBarActivationRunnable = new Runnable() {
@Override
public void run() {
mProgressBar.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
}
};
}
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Bundle args = getArguments();
if (!args.containsKey(ARG_POSITION_IN_VIEW_PAGER)) {
throw new IllegalStateException("Missing args. Please use newInstance()");
}
mFileLocalFabManager = FileLocalFabManager.getInstance();
mFileManager = FileManager.getInstance(getContext());
mFileImageManager = FileImageManager.getInstance(getContext());
mPositionInViewPager = args.getInt(ARG_POSITION_IN_VIEW_PAGER);
mFileLocalFabManager.addFabController(mPositionInViewPager, this);
}
@Override
public void onDestroy() {
mFileLocalFabManager.removeFabController(mPositionInViewPager);
super.onDestroy();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_file_image_local, container, false);
final Context context = getContext();
mStringDirectory = context.getString(R.string.file_image_model_directory);
mStringImage = context.getString(R.string.file_image_model_image);
mStringImages = context.getString(R.string.file_image_model_images);
mFileImageManager.registerAllLocalImageListener(this);
mFileImageManager.registerLocalImageFoldersListener(this);
mFileImageManager.registerLocalImageListener(this);
mProgressBar = (ProgressBar) rootView.findViewById(R.id.fragment_file_image_local_progress_bar);
mProgressBar.setVisibility(View.GONE);
mMessageTextView = (TextView) rootView.findViewById(R.id.fragment_file_image_local_message);
mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.fragment_file_image_local_swipe_refresh_layout);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_file_image_local_recycler_view);
mRecyclerView.setHasFixedSize(true);
updateGridLayoutManager();
mFileModels = new ArrayList<>();
mHeaderIds = new ArrayList<>();
mHeaderIds.add(new FileModelCardHeaderItem(R.id.view_file_header_image_folder, true));
mHeaderIds.add(new FileModelCardHeaderItem(R.id.view_file_header_image_recent, false));
mHeaderIds.add(new FileModelCardHeaderItem(R.id.view_file_header_image_artist, false));
mHeaderIds.add(new FileModelCardHeaderItem(R.id.view_file_header_image_album, false));
mHeaderIds.add(new FileModelCardHeaderItem(R.id.view_file_header_image_all, false));
mFileImageAdapter = new FileImageAdapter(mHeaderIds, this, getActivity(), mFileModels, new FileModelListener() {
@Override
public void executeFileModel(final FileModel fileModel, final View view) {
final AlertDialog.Builder menuAlert = new AlertDialog.Builder(getContext());
String[] menuList = {getString(R.string.rename), getString(R.string.delete), getString(R.string.properties)};
if (Config.isLogged()) {
menuList = new String[]{getString(R.string.upload), getString(R.string.open_as), getString(R.string.rename), getString(R.string.delete), getString(R.string.properties)};
}
menuAlert.setTitle("Action");
menuAlert.setItems(menuList,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (!Config.isLogged()) {
item += 2;
}
switch (item) {
case 0:
if (fileModel.isDirectory()) {
Toast.makeText(getContext(), R.string.not_implemented, Toast.LENGTH_SHORT).show();
} else {
DialogUtils.alert(
getActivity(),
getString(R.string.upload), "Upload file " + fileModel.getName(),
getString(R.string.upload),
new DialogUtils.OnDialogUtilsListener() {
@Override
public void onDialogUtilsCalledBack() {
if (fileModel.getFile() != null) {
List<StringPair> parameters = mFileManager.getForUpload(fileModel);
(new TaskPost(getActivity(), Constants.URL_DOMAIN + Config.ROUTE_FILE, new IPostExecuteListener() {
@Override
public void onPostExecute(JSONObject json, String body) {
}
}, parameters, fileModel.getFile())).execute();
}
}
}, getString(android.R.string.cancel), null);
}
break;
case 1:
mFileManager.openLocalAs(getActivity(), fileModel);
break;
case 2:
DialogUtils.prompt(
getActivity(),
"Rename",
"Rename " + (fileModel.isDirectory() ? "directory" : "file") + " " + fileModel.getName() + " ?",
"Ok",
new DialogUtils.OnDialogUtilsStringListener() {
@Override
public void onDialogUtilsStringCalledBack(String text) {
mFileManager.rename(fileModel, text, mRefreshActivityAdapterListener);
}
}, "Cancel", null, fileModel.getFullName());
break;
case 3:
DialogUtils.alert(
getActivity(),
"Delete",
"Delete " + (fileModel.isDirectory() ? "directory" : "file") + " " + fileModel.getName() + " ?",
"Yes",
new DialogUtils.OnDialogUtilsListener() {
@Override
public void onDialogUtilsCalledBack() {
mFileManager.delete(fileModel, mRefreshActivityAdapterListener);
}
}, "No", null);
break;
case 4:
DialogUtils.alert(getActivity(),
getString(R.string.properties) + " : " + fileModel.getName(),
mFileManager.toSpanned(getContext(), fileModel),
"OK",
null,
null,
null);
break;
}
}
});
AlertDialog menuDrop = menuAlert.create();
menuDrop.show();
}
});
mFileImageAdapter.setOnItemClickListener(new FileImageAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if (mFileModels.get(position).isDirectory()) {
refreshListFoldersInside(mFileModels.get(position));
} else {
mFileManager.execute(getActivity(), position, mFileModels, view);
}
}
});
mFileModelCardAdapter = new FileModelCardAdapter(context, mHeaderIds, this, mFileModels, null, new FileModelCardAdapter.OnFileClickListener() {
@Override
public void onFileCardClick(View view, int position) {
refreshListFoldersInside(mFileModels.get(position));
}
}, null);
mFileModelCardAdapter.setOnFileSubtitleAdapter(this);
mFileModelCardAdapter.setHeaderType(FileModelCardAdapter.TYPE_HEADER_IMAGE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mScaleAnimationAdapter = new ScaleAnimationAdapter(mRecyclerView, mFileModelCardAdapter);
mScaleAnimationAdapter.setDuration(220);
mScaleAnimationAdapter.setOffsetDuration(32);
mScaleAnimationAdapter.setNoAnimatedPosition(FileImageLocalFragment.this);
mRecyclerView.setAdapter(mScaleAnimationAdapter);
} else {
mRecyclerView.setAdapter(mFileModelCardAdapter);
}
refreshListFolders();
if (context instanceof AppCompatActivity) {
((AppCompatActivity) context).invalidateOptionsMenu();
}
return rootView;
}
@Override
public void onDestroyView() {
mFileImageManager.unregisterAllLocalImageListener(this);
mFileImageManager.unregisterLocalImageFoldersListener(this);
mFileImageManager.unregisterLocalImageListener(this);
super.onDestroyView();
}
@Override
public boolean back() {
if (mCurrentPage == PAGE_FOLDER_INSIDE) {
refreshListFolders();
return true;
}
return false;
}
@Override
public void onFabClick(
final @IntRange(from = 0, to = FileLocalFabManager.NUMBER_MAX_OF_FAB - 1) int fabPosition,
final @NonNull FloatingActionButton fab) {
if (fabPosition == 0) {
refreshListFolders();
}
}
@Override
public boolean isFabVisible(
final @IntRange(from = 0, to = FileLocalFabManager.NUMBER_MAX_OF_FAB - 1) int fabPosition) {
return fabPosition == 0 && mCurrentPage == PAGE_FOLDER_INSIDE;
}
@DrawableRes
@Override
public int getFabImageResource(
final @IntRange(from = 0, to = FileLocalFabManager.NUMBER_MAX_OF_FAB - 1) int fabPosition) {
return R.drawable.arrow_up;
}
@Nullable
@Override
public String onFileSubtitleModify(final FileModel fileModel) {
if (fileModel != null && fileModel.isDirectory() && fileModel.getCountImage() != 0) {
return mStringDirectory + ": " + StringUtils.longToShortString(fileModel.getCountImage())
+ " " + (fileModel.getCountImage() > 1 ? mStringImages : mStringImage);
}
return null;
}
@Override
public boolean onHeaderClick(View v, List<FileModelCardHeaderItem> fileModelCardHeaderItems) {
mHeaderIds.clear();
mHeaderIds.addAll(fileModelCardHeaderItems);
final int viewId = v.getId();
switch (viewId) {
case R.id.view_file_header_image_folder:
refreshListFolders();
break;
case R.id.view_file_header_image_recent:
//TODO
break;
case R.id.view_file_header_image_artist:
//TODO
break;
case R.id.view_file_header_image_album:
//TODO
break;
case R.id.view_file_header_image_all:
refreshListAllMusic();
break;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void onAllLocalImageSucceeded(List<FileModel> fileModels) {
hideProgressBar();
if (mFileModels == null) {
mFileModels = new ArrayList<>();
} else {
mFileModels.clear();
}
mFileModels.addAll(fileModels);
mFileImageAdapter.setHasHeader(true);
mScaleAnimationAdapter = new ScaleAnimationAdapter(mRecyclerView, mFileImageAdapter);
mScaleAnimationAdapter.setDuration(220);
mScaleAnimationAdapter.setOffsetDuration(32);
mScaleAnimationAdapter.setNoAnimatedPosition(FileImageLocalFragment.this);
mRecyclerView.setAdapter(mScaleAnimationAdapter);
updateAdapter();
}
/**
* {@inheritDoc}
*/
@Override
public void onAllLocalImageFailed() {
updateAdapter();
}
/**
* {@inheritDoc}
*/
@Override
public void onLocalImageFoldersSucceeded(List<FileModel> fileModels) {
hideProgressBar();
if (mFileModels == null) {
mFileModels = new ArrayList<>();
} else {
mFileModels.clear();
}
mFileModels.addAll(fileModels);
mScaleAnimationAdapter = new ScaleAnimationAdapter(mRecyclerView, mFileModelCardAdapter);
mScaleAnimationAdapter.setDuration(220);
mScaleAnimationAdapter.setOffsetDuration(32);
mScaleAnimationAdapter.setNoAnimatedPosition(FileImageLocalFragment.this);
mRecyclerView.setAdapter(mScaleAnimationAdapter);
updateAdapter();
}
/**
* {@inheritDoc}
*/
@Override
public void onLocalImageFoldersFailed() {
hideProgressBar();
}
/**
* {@inheritDoc}
*/
@Override
public void onLocalImageSucceeded(List<FileModel> fileModels) {
mFileModels.clear();
mFileModels.addAll(fileModels);
mFileImageAdapter.setHasHeader(false);
mScaleAnimationAdapter = new ScaleAnimationAdapter(mRecyclerView, mFileImageAdapter);
mScaleAnimationAdapter.setDuration(220);
mScaleAnimationAdapter.setOffsetDuration(32);
mScaleAnimationAdapter.setNoAnimatedPosition(FileImageLocalFragment.this);
mRecyclerView.setAdapter(mScaleAnimationAdapter);
updateAdapter();
}
/**
* {@inheritDoc}
*/
@Override
public void onLocalImageFailed() {
updateAdapter();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isAnimatedItem(int position) {
return mCurrentPage == PAGE_FOLDER_INSIDE || position != 0;
}
/**
* {@inheritDoc}
*/
@Override
public void onRefresh() {
mSwipeRefreshLayout.setRefreshing(false);
}
/**
* {@inheritDoc}
*/
@Override
public void refreshCurrentList() {
switch (mCurrentPage) {
case PAGE_ALL:
mFileImageManager.getAllLocalImage();
break;
case PAGE_FOLDERS:
mFileImageManager.getLocalImageFolders();
break;
case PAGE_FOLDER_INSIDE:
mFileImageManager.getLocalImage(mCurrentFolder);
break;
}
}
/**
* {@inheritDoc}
*/
@Override
public void scrollTop() {
mRecyclerView.smoothScrollToPosition(0);
}
public void refreshListFolders() {
mCurrentFolder = null;
mCurrentPage = PAGE_FOLDERS;
if (mFileManager == null) {
return;
}
showProgressBar();
mFileImageManager.getLocalImageFolders();
}
public void refreshListAllMusic() {
mCurrentPage = PAGE_ALL;
if (mFileManager == null) {
return;
}
showProgressBar();
mFileImageManager.getAllLocalImage();
}
public void refreshListFoldersInside(final FileModel fileModel) {
mCurrentFolder = fileModel;
mCurrentPage = PAGE_FOLDER_INSIDE;
mFileModels.clear();
mFileImageManager.getLocalImage(fileModel);
}
public void updateAdapter() {
if (mRecyclerView != null && mFileModels != null && isAdded()) {
mFileLocalFabManager.updateFabButtons();
if (mFileModels.size() == 0) {
mMessageTextView.setText(getString(R.string.no_image));
mMessageTextView.setVisibility(View.VISIBLE);
} else {
mMessageTextView.setVisibility(View.GONE);
}
if (mCurrentPage == PAGE_FOLDERS) {
updateGridLayoutManager();
mFileModelCardAdapter.setList(mFileModels);
} else {
updateStaggeredGridLayoutManager();
mFileImageAdapter.setList(mFileModels);
}
}
}
private void showProgressBar() {
mProgressBarActivationHandler.postDelayed(mProgressBarActivationRunnable, 200);
}
private void hideProgressBar() {
mProgressBarActivationHandler.removeCallbacks(mProgressBarActivationRunnable);
mProgressBar.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
}
private void updateGridLayoutManager() {
final GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(),
getResources().getInteger(R.integer.column_number_small_card));
mRecyclerView.setLayoutManager(gridLayoutManager);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return mFileModelCardAdapter.isHeader(position) && mCurrentPage != PAGE_FOLDER_INSIDE ?
gridLayoutManager.getSpanCount() : 1;
}
});
}
private void updateStaggeredGridLayoutManager() {
final StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(
getResources().getInteger(R.integer.column_number_small_card), StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(staggeredGridLayoutManager);
}
}