/*
 *  Copyright (C) 2006-2013  Ronald Blankendaal
 *  
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
package org.dbgl.util.searchengine;

import java.io.IOException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.dbgl.model.SearchEngineImageInformation;
import org.dbgl.model.WebProfile;
import org.dbgl.model.SearchEngineImageInformation.SearchEngineImageType;
import org.dbgl.swtdesigner.SWTImageManager;
import org.eclipse.swt.graphics.ImageData;
import org.apache.commons.lang3.StringUtils;


public class PouetSearchEngine extends WebSearchEngine {

	private static final String HTML_MULTIPLE_RESULT_MARKER_START = "<tr bgcolor=\"#557799\"><td nowrap><table cellspacing=\"0\" cellpadding=\"0\"><tr><td nowrap>";
	private static final String HTML_NEXT_RESULT_MARKER_START = "<td nowrap><table cellspacing=\"0\" cellpadding=\"0\"><tr><td nowrap>";
	private static final String HTML_GAME_END_MARKER = "     </tr>";

	private final static String HOST_NAME = "pouet.net";


	private PouetSearchEngine() {}

    private static class SearchEngineHolder {
        private static WebSearchEngine instance = new PouetSearchEngine();
    }

    public static WebSearchEngine getInstance() {
        return SearchEngineHolder.instance;
    }

    public String getIcon() {
		return SWTImageManager.IMG_POUET;
	}
    
    public String getName() {
		return "Pou\u00EBt.net";
	}
    
    public String getSimpleName() {
		return "pouet";
	}
    
	public List<WebProfile> getEntries(final String title, String[] platforms) throws IOException {
		int pageIdx = 0;
		int pages = 1;
		List<WebProfile> allEntries = new ArrayList<WebProfile>();

		while (pageIdx < pages) {
			String content = getResponseContent(HTTP_PROTOCOL + HOST_NAME + "/search.php?type=prod&what="
					+ URLEncoder.encode(title.replaceAll("/", " "), "ISO-8859-1") + "&page=" + (pageIdx + 1), "ISO-8859-1");
			if (pageIdx == 0)
				pages = getPages(content);
			allEntries.addAll(extractEntries(content));
			pageIdx++;
		}

		return filterEntries(platforms, allEntries);
	}

	private static int getPages(String htmlChunk) {
		int i = htmlChunk.indexOf("<select name=\"page\">");
		if (i != -1) {
			int j = htmlChunk.indexOf(HTML_B_OPEN, i);
			int k = htmlChunk.indexOf(' ', j);
			int l = htmlChunk.indexOf(HTML_B_CLOSE, k);
			return Integer.parseInt(htmlChunk.substring(k + 1, l));
		} else {
			return 0;
		}
	}

	private static List<WebProfile> extractEntries(String html) {
		List<WebProfile> allEntries = new ArrayList<WebProfile>();
		html = html.replaceAll("\\\\\"", "\"");
		int gameMatchEntryIndex = html.indexOf(HTML_MULTIPLE_RESULT_MARKER_START);
		if (gameMatchEntryIndex != -1)
			gameMatchEntryIndex += HTML_MULTIPLE_RESULT_MARKER_START.length();

		while (gameMatchEntryIndex != -1) {

			String category = "";
			String imgTypeData = extractNextContent(html, gameMatchEntryIndex, HTML_ANCHOR_OPEN, HTML_ANCHOR_CLOSE);
			int typeTitle1 = imgTypeData.indexOf("title=\"");
			int typeTitle2 = imgTypeData.indexOf("\"", typeTitle1 + 7);
			if (typeTitle1 != -1 && typeTitle2 != -1)
				category = imgTypeData.substring(typeTitle1 + 7, typeTitle2);
			category = StringUtils.capitalize(category);
			
			gameMatchEntryIndex = html.indexOf("<td nowrap>", gameMatchEntryIndex);

			int startGameTitleIdx = gameMatchEntryIndex;
			int gameTitleIdx = gameMatchEntryIndex;
			String gameTitleData = extractNextContent(html, gameTitleIdx, HTML_ANCHOR_OPEN, HTML_ANCHOR_CLOSE);
			String gameTitle = unescapeHtml(removeAllTags(gameTitleData));
			gameTitle = StringUtils.capitalize(gameTitle);
			String url = extractNextHrefContent(html, gameTitleIdx);
			url = absoluteUrl(HOST_NAME, url);

			int endGameTitleIdx = html.indexOf("</table></td>", gameTitleIdx);
			gameTitleIdx = html.indexOf(HTML_TD_OPEN, endGameTitleIdx);
			
			String developerName = extractNextContent(html, gameTitleIdx + 4, HTML_ANCHOR_OPEN, HTML_ANCHOR_CLOSE);
			developerName = StringUtils.capitalize(developerName);
			
			gameTitleIdx = html.indexOf(HTML_TD_CLOSE, gameTitleIdx);
			
			gameTitleIdx = html.indexOf(HTML_TD_CLOSE, gameTitleIdx);
			gameTitleIdx = html.indexOf(HTML_TD_OPEN, gameTitleIdx);
			
			String year = extractNextContent(html, gameTitleIdx + 4, HTML_TD_OPEN, HTML_TD_CLOSE);
			if (year.endsWith("<br />")) year = year.substring(0, year.length() - 6);
			if (year.indexOf(' ') != -1) {
				year = year.substring(year.indexOf(' ') + 1);
			} else {
				year = "";
			}
			
			gameTitleIdx = html.indexOf(HTML_TD_CLOSE, gameTitleIdx);
			gameTitleIdx = html.indexOf("<table cellspacing=\"0\" cellpadding=\"0\"><tr><td>&nbsp;</td>", gameTitleIdx);
			int rank = 0;
			try {
				String score = extractNextContent(html, gameTitleIdx + 58, HTML_TD_OPEN, HTML_TD_CLOSE);
				rank = (int)((Double.parseDouble(score) + 1.0) * 50.0);
			} catch (Exception e) {}
			
			String details =  html.substring(startGameTitleIdx, endGameTitleIdx);
			int platformIdx = details.indexOf("<td align=\"right\">");

			while (platformIdx != -1) {
				String platform = "";
				String imgPlatformData = extractNextContent(details, platformIdx, HTML_ANCHOR_OPEN, HTML_ANCHOR_CLOSE);
				int platformTitle1 = imgPlatformData.indexOf("title=\"");
				int platformTitle2 = imgPlatformData.indexOf("\"", platformTitle1 + 7);
				if (platformTitle1 != -1 && platformTitle2 != -1)
					platform = imgPlatformData.substring(platformTitle1 + 7, platformTitle2);

				WebProfile gameEntry = new WebProfile();
				gameEntry.setTitle(gameTitle);
				gameEntry.setUrl(url);
				gameEntry.setPlatform(platform);
				gameEntry.setPublisherName("");
				gameEntry.setDeveloperName(developerName);
				gameEntry.setYear(year);
				gameEntry.setGenre(category);
				gameEntry.setRank(rank);
				gameEntry.setNotes("");
				allEntries.add(gameEntry);
				
				platformIdx = details.indexOf("<td align=\"right\">", platformIdx + 1);
			}
			
			int endIdx = html.indexOf(HTML_GAME_END_MARKER, gameTitleIdx);
			gameMatchEntryIndex = html.indexOf(HTML_NEXT_RESULT_MARKER_START, endIdx + HTML_GAME_END_MARKER.length());
			if (gameMatchEntryIndex != -1)
				gameMatchEntryIndex += HTML_NEXT_RESULT_MARKER_START.length();
		}
		return allEntries;
	}

	public WebProfile getEntryDetailedInformation(final WebProfile entry) throws UnknownHostException, IOException {
		return entry;
	}

	public SearchEngineImageInformation[] getEntryImages(WebProfile entry, int coverArtMax, int screenshotsMax, boolean forceAllRegionsCoverArt) throws IOException {
		String html = getResponseContent(entry.getUrl(), "ISO-8859-1");
		int imgMatchEntryIndex = html.indexOf("<img src=\"screenshots/");
		if (imgMatchEntryIndex == -1) {
			entry.setWebImages(new SearchEngineImageInformation[0]);
		} else {
			String imgUrl = absoluteUrl(HOST_NAME, extractNextSrcContent(html, imgMatchEntryIndex));
			String imgDescription = getSimpleName();
			if (imgUrl.toLowerCase().endsWith(".gif")) {
				ImageData[] images = SWTImageManager.getAnimatedImageData(imgUrl);
				SearchEngineImageInformation[] result = new SearchEngineImageInformation[images.length];
				for (int i = 0; i < images.length; i++) {
					result[i] = new SearchEngineImageInformation(SearchEngineImageType.Screenshot, imgUrl, imgDescription);
					result[i].setData(images[i]);
				}
				entry.setWebImages(result);
			} else {
				entry.setWebImages(new SearchEngineImageInformation[] { new SearchEngineImageInformation(SearchEngineImageType.Screenshot, imgUrl, imgDescription)} );
			}
		}
		return entry.getWebImages();
	}
}
