/*
* This file is part of Spoutcraft.
*
* Copyright (c) 2011 SpoutcraftDev <http://spoutcraft.org/>
* Spoutcraft is licensed under the GNU Lesser General Public License.
*
* Spoutcraft is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Spoutcraft is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.spoutcraft.client.gui.database;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import org.yaml.snakeyaml.Yaml;
import org.bukkit.ChatColor;
import org.spoutcraft.api.gui.AbstractListModel;
import org.spoutcraft.api.gui.GenericListWidgetItem;
import org.spoutcraft.api.gui.ListWidgetItem;
import org.spoutcraft.client.SpoutClient;
import org.spoutcraft.client.gui.database.UrlElement;
public abstract class AbstractAPIModel extends AbstractListModel {
protected List<UrlElement> urlElements = new LinkedList<UrlElement>();
protected String API = "";
protected boolean loading = false;
protected Thread currentLoader = null;
protected int lastPage = 1;
protected String currentUrl = "";
protected boolean moreItems = false;
protected GenericListWidgetItem itemLoadNextItems = null;
protected ArrayList<Object> apiData = null;
protected GuiAPIDisplay currentGui = null;
protected List<ListWidgetItem> effectiveCache = null;
protected List<ListWidgetItem> entries = new ArrayList<ListWidgetItem>();
public void loadNextPage() {
lastPage++;
refreshAPIData(getCurrentUrl(), lastPage, false);
}
protected List<ListWidgetItem> getEffectiveList() {
List<ListWidgetItem> ret = new ArrayList<ListWidgetItem>();
for (ListWidgetItem item:entries) {
ret.add(item);
}
if (moreItems) {
itemLoadNextItems = new GenericListWidgetItem("More items on the server.", "Click to load", "");
ret.add(itemLoadNextItems);
}
return ret;
}
@Override
public ListWidgetItem getItem(int row) {
if (effectiveCache == null) {
effectiveCache = getEffectiveList();
sizeChanged();
}
if (row < 0 || row >= effectiveCache.size()) {
return null;
}
return effectiveCache.get(row);
}
@Override
public int getSize() {
if (effectiveCache == null) {
effectiveCache = getEffectiveList();
sizeChanged();
}
return effectiveCache.size();
}
public void refreshAPIData(final String url, final int page, final boolean clear) {
currentUrl = url;
if (currentLoader != null && currentLoader.isAlive()) {
currentLoader.interrupt();
System.out.println("Stopped previous loading");
}
currentLoader = new Thread() {
@SuppressWarnings("unchecked")
@Override
public void run() {
BufferedReader reader = null;
try {
System.setProperty("http.agent", "");
setLoading(true);
//long start = System.currentTimeMillis();
URL url1 = new URL(url + "&page=" + page);
//System.out.println("Loading " + url1.toString());
URLConnection conn = url1.openConnection();
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
Yaml yaml = new Yaml();
ArrayList<Object> yamlObj = (ArrayList<Object>) yaml.load(reader);
//System.out.println("Loaded in " + (System.currentTimeMillis() - start) + " ms");
apiData = yamlObj;
HashMap<String, Object> hash = (HashMap<String, Object>) apiData.remove(0);
int after = Integer.valueOf((String) hash.get("after"));
moreItems = after > 0;
refreshList(clear);
} catch (IOException e1) {
e1.printStackTrace();
// Put a fancy error message on the list!
clear();
effectiveCache = new LinkedList<ListWidgetItem>();
//String error = e1.getClass().getSimpleName().replaceAll("Exception", "");
//error = error.replaceAll("([A-Z])", " $1").trim();
effectiveCache.add(new GenericListWidgetItem(ChatColor.RED + "Could not load items!", e1.getMessage(), ""));
return;
} catch (Exception e) {
}
finally {
setLoading(false);
try {
reader.close();
} catch (Exception e) {
}
}
}
};
currentLoader.start();
}
public void clear() {
entries.clear();
if (effectiveCache != null) {
effectiveCache.clear();
}
moreItems = false;
}
protected abstract void refreshList(boolean clear);
public boolean isLoading() {
return loading;
}
public void setLoading(boolean l) {
loading = l;
if (currentGui != null) {
currentGui.updateButtons();
}
}
public void clearElementFilters() {
for (UrlElement element: urlElements) {
element.clear();
}
}
public void addUrlElement(UrlElement el) {
urlElements.add(el);
}
public void clearUrlElements() {
urlElements.clear();
}
public GuiAPIDisplay getCurrentGui() {
return currentGui;
}
public void updateUrl() {
String url = API + "?";
int i = 0;
for (UrlElement element:urlElements) {
if (element.isActive()) {
if (i > 0) {
url+="&";
}
url += element.getUrlPart();
i++; // Only increment for active elements
}
}
if (i != 0) {
refreshAPIData(url, 0, true);
}
}
public void update() {
effectiveCache = null;
}
public void setCurrentGui(GuiAPIDisplay gui) {
currentGui = gui;
}
public abstract String getDefaultUrl();
public String getCurrentUrl() {
return currentUrl;
}
public ArrayList<Object> getAPIData() {
synchronized (apiData) {
return apiData;
}
}
@Override
public void onSelected(int item, boolean doubleClick) {
if (currentGui != null) {
currentGui.updateButtons();
}
if (effectiveCache.get(item) == itemLoadNextItems) {
loadNextPage();
itemLoadNextItems.setTitle("Loading ...");
itemLoadNextItems.setText("Please wait ...");
}
}
}