/*
* Artcodes recognises a different marker scheme that allows the
* creation of aesthetically pleasing, even beautiful, codes.
* Copyright (C) 2013-2016 The University of Nottingham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package uk.ac.horizon.artcodes.adapter;
import android.content.Context;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.databinding.ViewDataBinding;
import android.support.annotation.DrawableRes;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.ViewGroup;
import uk.ac.horizon.artcodes.BR;
import uk.ac.horizon.artcodes.R;
public abstract class ListAdapter<T extends ViewDataBinding> extends BaseObservable
{
private static class BindViewHolder<T extends ViewDataBinding> extends RecyclerView.ViewHolder
{
private final T binding;
public BindViewHolder(T binding)
{
super(binding.getRoot());
this.binding = binding;
}
}
private int loading = 0;
private String emptyMessage;
private int emptyIcon = R.drawable.ic_warning_black_144dp;
private String errorMessage;
private String emptyDetail = "";
private static final int errorIcon = R.drawable.ic_warning_black_144dp;
private boolean error = false;
protected final Context context;
protected final RecyclerView.Adapter<BindViewHolder<T>> adapter = new RecyclerView.Adapter<BindViewHolder<T>>()
{
@Override
public int getItemViewType(final int position)
{
return getViewType(position);
}
@Override
public BindViewHolder<T> onCreateViewHolder(final ViewGroup parent, final int viewType)
{
return new BindViewHolder<>(createBinding(parent, viewType));
}
@Override
public void onBindViewHolder(final BindViewHolder<T> holder, final int position)
{
bind(position, holder.binding);
}
@Override
public int getItemCount()
{
return getViewCount();
}
};
protected ListAdapter(final Context context)
{
this.context = context;
this.emptyMessage = context.getString(R.string.empty);
}
@Bindable
public RecyclerView.Adapter getAdapter()
{
return adapter;
}
@Bindable
public RecyclerView.LayoutManager getLayoutManager()
{
return new LinearLayoutManager(context);
}
public abstract T createBinding(ViewGroup parent, int viewType);
public abstract void bind(int position, T binding);
public abstract int getViewCount();
public void setEmptyMessage(String message)
{
this.emptyMessage = message;
notifyPropertyChanged(BR.errorMessage);
}
public void setEmptyIcon(@DrawableRes int icon)
{
this.emptyIcon = icon;
notifyPropertyChanged(BR.errorIcon);
}
public void setEmptyDetail(String message)
{
this.emptyDetail = message;
notifyPropertyChanged(BR.errorDetail);
}
@Bindable
public RecyclerView.ItemDecoration getDecoration()
{
return null;
}
@Bindable
public boolean getShowError()
{
return !isLoading() && getViewCount() == 0;
}
@Bindable
public String getErrorMessage()
{
return error ? errorMessage : emptyMessage;
}
@DrawableRes
@Bindable
public int getErrorIcon()
{
return error ? errorIcon : emptyIcon;
}
@Bindable
public String getErrorDetail()
{
return error ? "" : emptyDetail;
}
@Bindable
public boolean isLoading()
{
return loading > 0;
}
public void loadStarted()
{
loading++;
if (loading == 1)
{
notifyPropertyChanged(BR.loading);
notifyPropertyChanged(BR.showError);
}
}
protected int getViewType(int position)
{
return 0;
}
protected void showEmpty()
{
error = false;
notifyPropertyChanged(BR.errorIcon);
notifyPropertyChanged(BR.errorMessage);
notifyPropertyChanged(BR.showError);
}
protected void showError(String errorMessage)
{
error = true;
this.errorMessage = errorMessage;
notifyPropertyChanged(BR.errorIcon);
notifyPropertyChanged(BR.errorMessage);
notifyPropertyChanged(BR.showError);
}
public void loadFinished()
{
loading--;
if (loading <= 0)
{
if (loading < 0)
{
Log.i("a", "Attempted to finish a load that never started");
}
loading = 0;
notifyPropertyChanged(BR.loading);
notifyPropertyChanged(BR.showError);
}
}
}