package com.cellasoft.univrapp.widget;
import android.widget.SectionIndexer;
import com.cellasoft.univrapp.utils.Lists;
import java.util.*;
public class ContactsSectionIndexer implements SectionIndexer {
private static String OTHER = "#";
private static String[] mSections;
private static int OTHER_INDEX = 0; // index of other in the mSections array
private int[] mPositions; // store the list of starting position index
// for
// each section
// e.g. A start at index 0, B start at index
// 20,
// C start at index 41 and so on
private int mCount; // this is the count for total number of contacts
// Assumption: the contacts array has been sorted
public ContactsSectionIndexer(List<ContactItemInterface> contacts) {
initPositions(contacts);
}
public ContactsSectionIndexer() {
}
public String getFirstLetterForIndex(String indexableItem) {
if (indexableItem != null) {
indexableItem = indexableItem.trim();
if (indexableItem.length() > 0)
return indexableItem.substring(0, 1).toUpperCase(
Locale.getDefault());
}
return "";
}
public String getSectionTitle(String indexableItem) {
int sectionIndex = getSectionIndex(indexableItem);
return mSections[sectionIndex];
}
// return which section this item belong to
public int getSectionIndex(String indexableItem) {
if (indexableItem == null) {
return OTHER_INDEX;
}
indexableItem = indexableItem.trim();
if (indexableItem.length() == 0) {
return OTHER_INDEX;
}
// get the first letter
String firstLetter = getFirstLetterForIndex(indexableItem);
int sectionCount = mSections.length;
for (int i = 0; i < sectionCount; i++) {
if (mSections[i].equals(firstLetter)) {
return i;
}
}
return OTHER_INDEX;
}
// initialize the position index
public void initPositions(List<ContactItemInterface> contacts) {
Collections.sort(contacts, new ContactItemComparator());
mCount = contacts.size();
HashMap<String, Integer> alphaIndexer = new HashMap<String, Integer>();
alphaIndexer.put(OTHER, OTHER_INDEX);
// Assumption: list of items have already been sorted by the prefer
// names
int itemIndex = 0;
for (ContactItemInterface contact : contacts) {
String ch = getFirstLetterForIndex(contact.getItemForIndex());
if (!alphaIndexer.containsKey(ch)) {
alphaIndexer.put(ch, itemIndex);
}
itemIndex++;
}
// init order section
Set<String> sectionLetters = alphaIndexer.keySet();
List<String> sectionList = Lists.newArrayList(sectionLetters
.toArray(new String[0]));
Collections.sort(sectionList);
mSections = new String[sectionList.size()];
sectionList.toArray(mSections);
sectionList.clear();
// init position for section
itemIndex = 0;
mPositions = new int[mSections.length];
Arrays.fill(mPositions, -1); // initialize everything to -1
for (String letter : mSections) {
mPositions[itemIndex] = alphaIndexer.get(letter);
itemIndex++;
}
alphaIndexer.clear();
alphaIndexer = null;
}
@Override
public int getPositionForSection(int section) {
if (section < 0 || section >= mSections.length) {
return -1;
}
return mPositions[section];
}
@Override
public int getSectionForPosition(int position) {
if (position < 0 || position >= mCount) {
return -1;
}
int index = Arrays.binarySearch(mPositions, position);
/*
* Consider this example: section positions are 0, 3, 5; the supplied
* position is 4. The section corresponding to position 4 starts at
* position 3, so the expected return value is 1. Binary search will not
* find 4 in the array and thus will return -insertPosition-1, i.e. -3.
* To get from that number to the expected value of 1 we need to negate
* and subtract 2.
*/
return index >= 0 ? index : -index - 2;
}
@Override
public Object[] getSections() {
return mSections;
}
// if first item in section, then return the section
// otherwise return -1
public boolean isFirstItemInSection(int position) { // check whether this
// item is the first
// item in section
return Arrays.binarySearch(mPositions, position) > -1;
}
}