package com.fatima.life2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;
import android.util.Log;
import com.limegroup.gnutella.Endpoint;
import com.limegroup.gnutella.RemoteFileDesc;
import com.limegroup.gnutella.URN;
import com.limegroup.gnutella.search.HostData;
// This class is thread safe.
public class SearchAdapter {
private HashMap<URN, P2pSearchResult> mResult = new HashMap<URN, P2pSearchResult>();
private int mSougouResultCount = 0;
// Provide a list view for representation.
private ArrayList<SearchResultBuffer> mResultBuffers = new ArrayList<SearchResultBuffer>();
private byte[] mGuid;
// For displaying.
private int mCurrentBatch;
public SearchAdapter(byte[] guid) {
mGuid = guid;
mCurrentBatch = 0;
}
public byte[] getGuid() {
return mGuid;
}
public void setGuid(byte[] guid) {
mGuid = guid;
}
public boolean sameGuid(byte[] guid) {
int size = guid.length;
for (int i = 0; i < size; i++)
if (this.mGuid[i] != guid[i]) {
return false;
}
return true;
}
public synchronized SearchResult get(int i) {
int bufferIndex = i / SearchResultBuffer.BUFFER_SIZE;
int bufferOffset = i % SearchResultBuffer.BUFFER_SIZE;
return mResultBuffers.get(bufferIndex).get(bufferOffset);
}
public synchronized int size() {
return mResult.size() + mSougouResultCount;
}
// Set loc is Endpoint.
//
// TODO: we can create RFD from it for now, we just ignore it
//
// Returns true if we need to refresh display.
public synchronized boolean add(RemoteFileDesc rfd, HostData data, Set<Endpoint> loc) {
if (rfd.getFileName() != null &&
rfd.getFileName().indexOf("LAWSUIT WARNING") != -1) {
return false;
}
URN sha1 = rfd.getSHA1Urn();
P2pSearchResult rs = mResult.get(sha1);
SearchResultBuffer lastBuffer = null;
if (!mResultBuffers.isEmpty())
lastBuffer = mResultBuffers.get(mResultBuffers.size() - 1);
boolean shouldRefresh = false;
if (rs == null) {
// A new search result.
rs = new P2pSearchResult(mGuid, rfd, data, loc);
mResult.put(sha1, rs);
if (lastBuffer != null && !lastBuffer.isFull()) {
lastBuffer.add(rs);
} else {
lastBuffer = new SearchResultBuffer();
lastBuffer.add(rs);
mResultBuffers.add(lastBuffer);
}
if (mCurrentBatch < mResultBuffers.size() && mResultBuffers.get(mCurrentBatch) == lastBuffer) {
shouldRefresh = true;
}
} else {
shouldRefresh = true;
// TODO: We may need to find the correponding buffer and resort it.
}
rs.add(rfd);
return shouldRefresh;
}
public synchronized boolean add(SogouSearchResult result) {
if (result == null)
return false;
SearchResultBuffer lastBuffer = null;
if (!mResultBuffers.isEmpty())
lastBuffer = mResultBuffers.get(mResultBuffers.size() - 1);
boolean shouldRefresh = false;
mSougouResultCount++;
if (lastBuffer != null && !lastBuffer.isFull()) {
lastBuffer.add(result);
} else {
lastBuffer = new SearchResultBuffer();
lastBuffer.add(result);
mResultBuffers.add(lastBuffer);
}
if (mCurrentBatch < mResultBuffers.size() && mResultBuffers.get(mCurrentBatch) == lastBuffer) {
shouldRefresh = true;
}
return shouldRefresh;
}
// Method for display..
public synchronized int displaySize() {
if (mResultBuffers.isEmpty())
return 0;
int lastDisplay = Math.min(mCurrentBatch, mResultBuffers.size() - 1);
return SearchResultBuffer.BUFFER_SIZE * lastDisplay + mResultBuffers.get(lastDisplay).size();
}
public synchronized void nextBatch() {
++mCurrentBatch;
}
public synchronized boolean isBatchFull() {
if (mResultBuffers.isEmpty())
return false;
if (mCurrentBatch >= mResultBuffers.size())
return false;
return mResultBuffers.get(mCurrentBatch).isFull();
}
}