package cc.hughes.droidchatty;

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

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

public abstract class LoadingAdapter<T> extends ArrayAdapter<T>
{
    protected abstract View createView(int position, View convertView, ViewGroup parent);
    protected abstract ArrayList<T> loadData() throws Exception;
    
    private List<T> _items;
    private int _loadingResource;
    private View _loadingView;
    
    public LoadingAdapter(Context context, int resource, int loadingResource, List<T> objects)
    {
        super(context, resource, 0, objects);
        _loadingResource = loadingResource;
        _items = objects;
    }
    
    public List<T> getItems()
    {
        return _items;
    }
    
    @Override
    public T getItem(int position)
    {
        if (position == super.getCount())
            return null;
        return super.getItem(position);
    }

    @Override
    public int getItemViewType(int position)
    {
        if (position == super.getCount())
            return IGNORE_ITEM_VIEW_TYPE;
        
        return super.getItemViewType(position);
    }

    @Override
    public int getViewTypeCount()
    {
        // regular view + loading view
        return super.getViewTypeCount() + 1;
    }
    
    @Override
    public int getCount()
    {
        return super.getCount() + 1;
    }
    
    @Override
    public void add(T item)
    {
        _items.add(item);
    }
    
    @Override
    public void clear()
    {
        _items.clear();
        super.clear();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        if (position == super.getCount())
        {
            if (_loadingView == null)
            {
                _loadingView = getLoadingView(parent);
                new LoadAndAppendTask().execute();
            }
            return _loadingView;
        }
        
        return createView(position, convertView, parent);
    }
    
    private View getLoadingView(ViewGroup parent)
    {
        LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        return inflater.inflate(_loadingResource, parent, false);
    }
    
    class LoadAndAppendTask extends AsyncTask<Void, Void, ArrayList<T>>
    {
        Exception _exception;
        
        @Override
        protected ArrayList<T> doInBackground(Void... arg0)
        {
            try
            {
                return loadData();
            }
            catch (Exception e)
            {
                Log.e("DroidChatty", "Error loading data.", e);
                _exception = e;
            }
            
            return null;
        }

        @Override
        protected void onPostExecute(ArrayList<T> result)
        {
            if (_exception != null)
            {
               ErrorDialog.display(getContext(), "Error", "Error loading data."); 
            }
            else if (result != null)
            {
                for (T item : result)
                    add(item);
                
                _loadingView = null;
                notifyDataSetChanged();
            }
        }
    }
    
}

@@ -612,21 +612,61 @@
 ngView;%0A
+    private boolean _moreToLoad = true;%0A
     %0A
-
     publ
@@ -1524,32 +1524,61 @@
 etCount()%0A    %7B%0A
+        if (_moreToLoad)%0A    
         return s
@@ -1590,32 +1590,65 @@
 getCount() + 1;%0A
+        return super.getCount();%0A
     %7D%0A    %0A    @
@@ -3128,32 +3128,68 @@
 )%0A            %7B%0A
+               _moreToLoad = false;%0A
                E
@@ -3312,32 +3312,192 @@
 )%0A            %7B%0A
+                if (result.size() == 0)%0A                %7B%0A                    _moreToLoad = false;%0A                %7D%0A                else%0A                %7B%0A    
                 
@@ -3510,32 +3510,36 @@
  item : result)%0A
+    
                 
@@ -3561,32 +3561,33 @@
                 
+%7D
 %0A               
@@ -3587,37 +3587,126 @@
     
-    _loadingView = null;%0A    
+%7D%0A            %0A            // dataset changed, either there are new items, or the count went down (no more %22Loading%22)%0A
     
@@ -3741,33 +3741,52 @@
 ();%0A            
-%7D
+_loadingView = null;
 %0A        %7D%0A    %7D

stop showing the 'Loading' item if there is nothing more to load