package org.sflphone.adapters;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.sflphone.R;
import org.sflphone.fragments.ContactListFragment;
import org.sflphone.model.CallContact;

import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SectionIndexer;
import android.widget.TextView;
import android.widget.Toast;

public class ContactsAdapter extends BaseAdapter implements SectionIndexer {

    private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
    Context mContext;

    HashMap<String, Integer> alphaIndexer;
    String[] sections;
    WeakReference<ContactListFragment> parent;

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

    public ContactsAdapter(ContactListFragment contactListFragment) {
        super();
        mContext = contactListFragment.getActivity();
        alphaIndexer = new HashMap<String, Integer>();
        headers = new HeadersHolder(new ArrayList<CallContact>());
        parent = new WeakReference<ContactListFragment>(contactListFragment);
    }

    HeadersHolder headers;
    private static final int TYPE_HEADER = 0;
    private static final int TYPE_TRACK = 1;

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        int type = getItemViewType(position);

        // Log.i(TAG, "positon" + position + " type " + type);
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        switch (type) {
        case TYPE_TRACK:
            return getViewContact(position, inflater, convertView);
        case TYPE_HEADER:
            return getViewHeader(position, inflater, convertView);
        }
        return null;
    }

    private View getViewHeader(int position, LayoutInflater inflater, View convertView) {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.header, null);
        }
        TextView name = (TextView) convertView.findViewById(R.id.header_letter);
        name.setText(headers.getSection(position));
        return convertView;
    }

    private View getViewContact(int position, LayoutInflater inflater, View convertView) {
        ContactView entryView;
        
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item_contact, null);

            entryView = new ContactView();
            entryView.quick_starred = (ImageButton) convertView.findViewById(R.id.quick_starred);
            entryView.quick_edit = (ImageButton) convertView.findViewById(R.id.quick_edit);
            entryView.quick_discard = (ImageButton) convertView.findViewById(R.id.quick_discard);
            entryView.quick_call = (ImageButton) convertView.findViewById(R.id.quick_call);
            entryView.quick_msg = (ImageButton) convertView.findViewById(R.id.quick_message);
            entryView.photo = (ImageView) convertView.findViewById(R.id.photo);
            entryView.display_name = (TextView) convertView.findViewById(R.id.display_name);
            convertView.setTag(entryView);
        } else {
            entryView = (ContactView) convertView.getTag();
        }
        

        final CallContact item = headers.getCallContact(position);

        entryView.display_name.setText(item.getmDisplayName());


        infos_fetcher.execute(new ContactPictureTask(mContext, entryView.photo, item.getId()));

        entryView.quick_call.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                parent.get().mCallbacks.onCallContact(item);

            }
        });
        
        entryView.quick_starred.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
            }
        });
        
        entryView.quick_edit.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                parent.get().mCallbacks.onEditContact(item);

            }
        });
        
        entryView.quick_discard.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();

            }
        });
        
        

        entryView.quick_msg.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                parent.get().mCallbacks.onTextContact(item);
            }
        });

        return convertView;
    }
    
    /*********************
     * ViewHolder Pattern
     *********************/
    public class ContactView {
        ImageButton quick_starred, quick_edit, quick_discard, quick_call, quick_msg;
        ImageView photo;
        TextView display_name;
    }

    @Override
    public int getCount() {
        return headers.size() + headers.getSections().size();
    }

    @Override
    public int getItemViewType(int pos) {
        return (headers.contains(pos) ? TYPE_HEADER : TYPE_TRACK);
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    public void removeAll() {
        headers.clear();
        notifyDataSetChanged();
    }

    public void add(CallContact tr) {
        headers.add(tr);
        headers.buildIndex();
    }

    public void addAll(ArrayList<CallContact> tr) {
        headers = new HeadersHolder(tr);
        notifyDataSetChanged();
    }

    @Override
    public int getPositionForSection(int section) {
        return headers.getPositionFor(section);
    }

    @Override
    public int getSectionForPosition(int position) {
        return headers.getSectionFor(position);
    }

    @Override
    public Object[] getSections() {
        return headers.getSectionsArray();
    }

    public int getRealPosition(int pos) {
        return headers.getTrackPosition(pos);
    }

    @Override
    public CallContact getItem(int index) {
        return headers.getCallContact(index);
    }

    public class HeadersHolder {

        public static final String TAG = "HeadersHolder";
        HashMap<String, Integer> alphaIndexer;
        ArrayList<CallContact> contacts;

        String[] sectionsArray;

        public String[] getSectionsArray() {
            return sectionsArray;
        }

        int headersCount;
        private SparseArray<Item> items = new SparseArray<Item>();

        public SparseArray<Item> getItems() {
            return items;
        }

        public void setItems(SparseArray<Item> items) {
            this.items = items;
        }

        public SparseArray<Section> getSections() {
            return sections;
        }

        public void setSections(SparseArray<Section> sections) {
            this.sections = sections;
        }

        private SparseArray<Section> sections = new SparseArray<Section>();

        public HeadersHolder(ArrayList<CallContact> a) {
            alphaIndexer = new HashMap<String, Integer>();
            contacts = a;
            headersCount = 0;
            buildIndex();
        }

        // public int getHeadersCount() {
        // return headersCount;
        // }

        private class Item {
            public Item(int rpos, int headersCount2, CallContact track) {
                // Log.i(TAG, "Creating Item");

                sectionNumber = headersCount2;
                realPos = rpos;
                tr = track;

            }

            public int realPos;
            public int sectionNumber;
            public CallContact tr;
        }

        private class Section {
            // public int startPosition;
            public int number;
            public String header;

            public Section(int i, int headersCount, String str) {
                // Log.i(TAG, "Creating section");

                // startPosition = i + headersCount;
                number = headersCount;
                header = str;

            }

            @Override
            public String toString() {
                return header;
            }
        }

        public void buildIndex() {

            for (int x = 0; x < contacts.size(); x++) {
                String s = contacts.get(x).getmDisplayName();
                String ch = s.substring(0, 1);
                ch = ch.toUpperCase(Locale.CANADA);
                if (!alphaIndexer.containsKey(ch)) {
                    sections.put(x + headersCount, new Section(x, headersCount, ch));
                    headersCount++;
                }
                Integer result = alphaIndexer.put(ch, x + headersCount);
                items.put(x + headersCount, new Item(x, headersCount, contacts.get(x)));
                if (result == null) {

                }
            }

            Set<String> sect = alphaIndexer.keySet();

            // create a list from the set to sort
            ArrayList<String> sectionList = new ArrayList<String>(sect);
            Collections.sort(sectionList);
            sectionsArray = new String[sectionList.size()];
            sectionList.toArray(sectionsArray);

        }

        public HashMap<String, Integer> getAlphaIndexer() {
            return alphaIndexer;
        }

        public int getPositionFor(int section) {
            if (section == sectionsArray.length)
                return sectionsArray.length;
            return alphaIndexer.get(sectionsArray[section]);
        }

        public int getSectionFor(int position) {
            return (null != items.get(position)) ? items.get(position).sectionNumber : sections.get(position).number;
        }

        public boolean contains(int pos) {
            if (sections.get(pos) != null) {
                return true;
            }
            return false;
        }

        public CallContact getCallContact(int position) {

            if (items.get(position) == null)
                return null;

            return items.get(position).tr;

        }

        public int size() {
            return contacts.size();
        }

        public void clear() {
            contacts.clear();

        }

        public void add(CallContact tr) {
            contacts.add(tr);

        }

        public void addAll(ArrayList<CallContact> tr) {
            contacts.clear();
            contacts.addAll(tr);

        }

        public ArrayList<CallContact> getTracks() {
            return contacts;
        }

        public int getTrackPosition(int pos) {
            if (sections.get(pos) != null) {
                return items.get(pos + 1).realPos;
            }
            return items.get(pos).realPos;
        }

        public CharSequence getSection(int position) {
            return sections.get(position).header;
        }

    }

}
