package treehou.se.habit.ui.adapter;
import android.content.Context;
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.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import se.treehou.ng.ohcommunicator.connector.models.OHServer;
import se.treehou.ng.ohcommunicator.connector.models.OHSitemap;
import treehou.se.habit.R;
public class SitemapAdapter extends RecyclerView.Adapter<SitemapAdapter.SitemapBaseHolder>{
private static final String TAG = SitemapAdapter.class.getSimpleName();
private Context context;
private Map<OHServer, SitemapItem> items = new HashMap<>();
private OnSitemapSelectListener selectorListener;
public static class SitemapItem{
public static final int STATE_SUCCESS = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_ERROR = 2;
public OHServer server;
public int state = STATE_LOADING;
public List<OHSitemap> sitemaps = new ArrayList<>();
public SitemapItem(OHServer server) {
this.server = server;
}
public void addItem(OHSitemap sitemap){
sitemaps.add(sitemap);
state = STATE_SUCCESS;
}
}
public class SitemapBaseHolder extends RecyclerView.ViewHolder {
public TextView lblServer;
public SitemapBaseHolder(View itemView) {
super(itemView);
lblServer = (TextView) itemView.findViewById(R.id.lbl_server);
}
}
public class SitemapHolder extends SitemapBaseHolder {
public TextView lblName;
public SitemapHolder(View view) {
super(view);
lblName = (TextView) itemView.findViewById(R.id.lbl_sitemap);
}
}
public class SitemapErrorHolder extends SitemapBaseHolder {
public SitemapErrorHolder(View view) {
super(view);
}
}
public class SitemapLoadHolder extends SitemapBaseHolder {
public SitemapLoadHolder(View view) {
super(view);
}
}
public class GetResult {
public SitemapItem item;
public OHSitemap sitemap;
public GetResult(SitemapItem item, OHSitemap sitemap) {
this.sitemap = sitemap;
this.item = item;
}
}
public SitemapAdapter(Context context) {
this.context = context;
}
@Override
public SitemapBaseHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
LayoutInflater inflater = LayoutInflater.from(context);
if(SitemapItem.STATE_SUCCESS == type){
View itemView = inflater.inflate(R.layout.item_sitemap, null);
return new SitemapHolder(itemView);
}else if(SitemapItem.STATE_LOADING == type){
View itemView = inflater.inflate(R.layout.item_sitemap_load, null);
return new SitemapLoadHolder(itemView);
}else {
View serverLoadFail = inflater.inflate(R.layout.item_sitemap_failed,null);
return new SitemapErrorHolder(serverLoadFail);
}
}
@Override
public void onBindViewHolder(SitemapBaseHolder sitemapHolder, int position) {
int type = getItemViewType(position);
final GetResult item = getItem(position);
if(SitemapItem.STATE_SUCCESS == type){
SitemapHolder holder = (SitemapHolder) sitemapHolder;
final OHSitemap sitemap = item.sitemap;
holder.lblName.setText(item.sitemap.getName());
holder.lblServer.setText(item.sitemap.getServer().getName());
sitemapHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectorListener.onSitemapSelect(sitemap);
}
});
}else if(SitemapItem.STATE_LOADING == type){
SitemapLoadHolder holder = (SitemapLoadHolder) sitemapHolder;
holder.lblServer.setText(item.item.server.getName());
}else if(SitemapItem.STATE_ERROR == type){
SitemapErrorHolder holder = (SitemapErrorHolder) sitemapHolder;
holder.lblServer.setText(item.item.server.getName());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectorListener.onErrorClicked(item.item.server);
}
});
}
}
public interface OnSitemapSelectListener {
void onSitemapSelect(OHSitemap sitemap);
void onErrorClicked(OHServer server);
}
private class DummySelectListener implements OnSitemapSelectListener {
@Override
public void onSitemapSelect(OHSitemap sitemap) {}
@Override
public void onErrorClicked(OHServer server) {}
}
@Override
public int getItemViewType(int position) {
int count = 0;
for(SitemapItem item : items.values()){
if(SitemapItem.STATE_SUCCESS == item.state){
if(position >= count && position < (count+item.sitemaps.size())){
return SitemapItem.STATE_SUCCESS;
}
count += item.sitemaps.size();
}else if(SitemapItem.STATE_ERROR == item.state){
if(count == position){
return SitemapItem.STATE_ERROR;
}
count++;
}else if(SitemapItem.STATE_LOADING == item.state){
if(count == position){
return SitemapItem.STATE_LOADING;
}
count++;
}
}
return SitemapItem.STATE_LOADING;
}
@Override
public int getItemCount() {
int count = 0;
for(SitemapItem item : items.values()){
if(item.state == SitemapItem.STATE_SUCCESS){
count += item.sitemaps.size();
}else{
count++;
}
}
return count;
}
public GetResult getItem(int position) {
GetResult result = null;
int count = 0;
for(SitemapItem item : items.values()){
if(SitemapItem.STATE_SUCCESS == item.state){
for(OHSitemap sitemap : item.sitemaps){
if(count == position){
result = new GetResult(item, sitemap);
return result;
}
count++;
}
}else{
if(count == position){
result = new GetResult(item, null);
break;
}
count++;
}
}
return result;
}
public void addAll(List<OHSitemap> sitemaps){
for(OHSitemap sitemap : sitemaps){
add(sitemap);
}
}
public void add(OHSitemap sitemap) {
SitemapItem item = items.get(sitemap.getServer());
if(item == null){
item = new SitemapItem(sitemap.getServer());
items.put(item.server, item);
}
int count = getItemCount();
item.addItem(sitemap);
Log.d(TAG, "Added sitemap " + sitemap.getServer().getName() + " " + sitemap.getName() + " precount: " + count + " postcount: " + getItemCount() + " items: " + items.size());
notifyDataSetChanged();
}
public void remove(OHSitemap sitemap) {
int pos = findPosition(sitemap);
remove(sitemap, pos);
}
public void remove(OHSitemap sitemap, int position) {
SitemapItem item = items.get(sitemap.getServer());
if(item == null){
return;
}
item.sitemaps.remove(sitemap);
notifyItemRemoved(position);
}
private int findPosition(final OHSitemap pSitemap){
int count = 0;
for(SitemapItem item : items.values()){
if(SitemapItem.STATE_SUCCESS == item.state){
for(OHSitemap sitemap : item.sitemaps){
if(sitemap == pSitemap){
return count;
}
count++;
}
}else{
count++;
}
}
return -1;
}
public void setSelectorListener(OnSitemapSelectListener selectorListener) {
if(selectorListener == null) selectorListener = new DummySelectListener();
this.selectorListener = selectorListener;
}
public void setServerState(OHServer server, int state) {
SitemapItem item = items.get(server);
if(item == null){
item = new SitemapItem(server);
items.put(server, item);
}
item.state = state;
notifyDataSetChanged();
}
public boolean contains(OHSitemap sitemap){
return items.containsKey(sitemap.getServer()) && items.get(sitemap.getServer()).sitemaps.contains(sitemap);
}
public void clear(){
int last = items.size()-1;
items.clear();
notifyItemRangeRemoved(0, last);
}
}