/*
 * Copyright (C) 2004-2014 L2J DataPack
 * 
 * This file is part of L2J DataPack.
 * 
 * L2J DataPack 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 3 of the License, or
 * (at your option) any later version.
 * 
 * L2J DataPack 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, see <http://www.gnu.org/licenses/>.
 */
package quests.Q00662_AGameOfCards;

import java.util.ArrayList;

import jp.sf.l2j.arrayMaps.SortedIntIntArrayMap;

import com.l2jserver.gameserver.enums.QuestSound;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.model.quest.State;
import com.l2jserver.gameserver.util.Util;
import com.l2jserver.util.Rnd;

/**
 * A Game of Cards (662)
 * @author Zoey76
 */
public final class Q00662_AGameOfCards extends Quest
{
	// NPC
	private static final int KLUMP = 30845;
	// Items
	private static final int RED_GEM = 8765;
	private static final int ZIGGOS_GEMSTONE = 8868;
	// Misc
	private static final int MIN_LEVEL = 61;
	private static final int REQUIRED_CHIP_COUNT = 50;
	// Monsters
	private static final SortedIntIntArrayMap MONSTERS = new SortedIntIntArrayMap()
		.append(20672, 357) // Trives
		.append(20673, 357) // Falibati
		.append(20674, 583) // Doom Knight
		.append(20677, 435) // Tulben
		.append(20955, 358) // Ghostly Warrior
		.append(20958, 283) // Death Agent
		.append(20959, 455) // Dark Guard
		.append(20961, 365) // Bloody Knight
		.append(20962, 348) // Bloody Priest
		.append(20965, 457) // Chimera Piece
		.append(20966, 493) // Changed Creation
		.append(20968, 418) // Nonexistent Man
		.append(20972, 350) // Shaman of Ancient Times
		.append(20973, 453) // Forgotten Ancient People
		.append(21002, 315) // Doom Scout
		.append(21004, 320) // Dismal Pole
		.append(21006, 335) // Doom Servant
		.append(21008, 462) // Doom Archer
		.append(21010, 397) // Doom Warrior
		.append(21109, 507) // Hames Orc Scout
		.append(21112, 552) // Hames Orc Footman
		.append(21114, 587) // Cursed Guardian
		.append(21116, 812) // Hames Orc Overlord
		.append(21278, 483) // Antelope
		.append(21279, 483) // Antelope
		.append(21280, 483) // Antelope
		.append(21286, 515) // Buffalo
		.append(21287, 515) // Buffalo
		.append(21288, 515) // Buffalo
		.append(21508, 493) // Splinter Stakato
		.append(21510, 527) // Splinter Stakato Soldier
		.append(21513, 562) // Needle Stakato
		.append(21515, 598) // Needle Stakato Soldier
		.append(21520, 458) // Eye of Splendor
		.append(21526, 552) // Wisdom of Splendor
		.append(21530, 488) // Victory of Splendor
		.append(21535, 573) // Signet of Splendor
		.append(18001, 232) // Blood Queen
	;
	
	private Q00662_AGameOfCards(int questId, String name, String descr)
	{
		super(questId, name, descr);
		addStartNpc(KLUMP);
		addTalkId(KLUMP);
		addKillId(MONSTERS.keySet());
	}
	
	@Override
	public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
	{
		final QuestState st = player.getQuestState(getName());
		String htmltext = null;
		if (st == null)
		{
			return htmltext;
		}
		
		switch (event)
		{
			case "30845-03.htm":
			{
				if (player.getLevel() >= MIN_LEVEL)
				{
					st.setState(State.STARTED);
					st.setCond(1);	//[JOJO]
					st.playSound(QuestSound.ITEMSOUND_QUEST_ACCEPT);
					htmltext = event;
				}
				break;
			}
			case "30845-06.html":
			case "30845-08.html":
			case "30845-09.html":
			case "30845-09a.html":
			case "30845-09b.html":
			case "30845-10.html":
			{
				htmltext = event;
				break;
			}
			case "30845-07.html":
			{
				st.exitQuest(true, true);
				htmltext = event;
				break;
			}
			case "return":
			{
				htmltext = st.getQuestItemsCount(RED_GEM) < REQUIRED_CHIP_COUNT ? "30845-04.html" : "30845-05.html";
				break;
			}
			case "30845-11.html":
			{
				if (st.getQuestItemsCount(RED_GEM) >= REQUIRED_CHIP_COUNT)
				{
					final int c1 = getRandom(1, 14);
					final int c2 = getRandom(1, 14);
					final int c3 = getRandom(1, 14);
					final int c4 = getRandom(1, 14);
					final int c5 = getRandom(1, 14);
					
					st.set("ex", c5 << 16 | c4 << 12 | c3 << 8 | c2 << 4 | c1);
					st.takeItems(RED_GEM, REQUIRED_CHIP_COUNT);
					htmltext = event;
				}
				break;
			}
			case "turncard1":
			case "turncard2":
			case "turncard3":
			case "turncard4":
			case "turncard5":
			{
				int ex = st.getInt("ex");
				int turned = ex >>> 24 & 0b11111;	// カード5枚分
				final int c1 = ex        & 15;
				final int c2 = ex >>>  4 & 15;
				final int c3 = ex >>>  8 & 15;
				final int c4 = ex >>> 12 & 15;
				final int c5 = ex >>> 16 & 15;
				switch (event)
				{
					case "turncard1":
						turned |= 1;
						break;
					case "turncard2":
						turned |= 2;
						break;
					case "turncard3":
						turned |= 4;
						break;
					case "turncard4":
						turned |= 8;
						break;
					case "turncard5":
						turned |= 16;
						break;
				}
				int ax = ex | turned << 24;
				if (ex != ax)
				{
					ex = ax;
					st.set("ex", ex);
				}
				
				if (turned != 0b11111)	//if (Integer.bitCount(turned) != 5)
				{
					htmltext = getHtm(player.getHtmlPrefix(), "30845-12.html");
				}
				else
				{
					int count = 0;
					int[] cards = { c1, c2, c3, c4, c5 };
					for (int i = 0; i < 4; ++i)
						for (int j = i + 1; j < 5; ++j)
							if (cards[i] == cards[j])
								++count;
					cards = null;
					
					switch (count) {
						case 10:
							// ファイブ カード
							st.giveItems(ZIGGOS_GEMSTONE, 43);
							st.giveItems(959, 3);
							st.giveItems(729, 1);
							st.set("ex", 0);
							htmltext = getHtm(player.getHtmlPrefix(), "30845-13.html");
							break;
						case 6:
							// フォーカード
							st.giveItems(959, 2);
							st.giveItems(951, 2);
							st.set("ex", 0);
							htmltext = getHtm(player.getHtmlPrefix(), "30845-14.html");
							break;
						case 4:
							// フルハウス
							st.giveItems(729, 1);
							st.giveItems(947, 2);
							st.giveItems(955, 1);
							st.set("ex", 0);
							htmltext = getHtm(player.getHtmlPrefix(), "30845-15.html");
							break;
						case 3:
							// スリーカード
							st.giveItems(951, 2);
							st.set("ex", 0);
							htmltext = getHtm(player.getHtmlPrefix(), "30845-16.html");
							break;
						case 2:
							// ツーペア
							st.giveItems(951, 1);
							st.set("ex", 0);
							htmltext = getHtm(player.getHtmlPrefix(), "30845-17.html");
							break;
						case 1:
							// ワンペア
							st.giveItems(956, 2);
							st.set("ex", 0);
							htmltext = getHtm(player.getHtmlPrefix(), "30845-18.html");
							break;
						case 0:
							// ノーペア
							st.set("ex", 0);
							htmltext = getHtm(player.getHtmlPrefix(), "30845-19.html");
							break;
						default:
							throw new RuntimeException("count=" + count);
					}
				}
				
				if (htmltext != null)
				{
					htmltext = replaceCardsHtml(htmltext, ex);
				}
				break;
			}
			case "playagain":
			{
				htmltext = st.getQuestItemsCount(RED_GEM) < REQUIRED_CHIP_COUNT ? "30845-21.html" : "30845-20.html";
				break;
			}
		}
		return htmltext;
	}
	
	private static String replaceCardsHtml(String htmltext, int ex)
	{
		final int turned = ex >>> 24 & 0b11111;	// カード5枚分
		final int c1 = ex        & 15;
		final int c2 = ex >>>  4 & 15;
		final int c3 = ex >>>  8 & 15;
		final int c4 = ex >>> 12 & 15;
		final int c5 = ex >>> 16 & 15;
		
		if ((turned & 1) == 0)
		{
			htmltext = htmltext.replace("FontColor1", "FFFF00");
			htmltext = htmltext.replace("Cell1", "?");
		}
		else
		{
			htmltext = htmltext.replace("FontColor1", "FF6F6F");
			htmltext = replaceSymbol(htmltext, "Cell1", c1);
		}
		if ((turned & 2) == 0)
		{
			htmltext = htmltext.replace("FontColor2", "FFFF00");
			htmltext = htmltext.replace("Cell2", "?");
		}
		else
		{
			htmltext = htmltext.replace("FontColor2", "FF6F6F");
			htmltext = replaceSymbol(htmltext, "Cell2", c2);
		}
		if ((turned & 4) == 0)
		{
			htmltext = htmltext.replace("FontColor3", "FFFF00");
			htmltext = htmltext.replace("Cell3", "?");
		}
		else
		{
			htmltext = htmltext.replace("FontColor3", "FF6F6F");
			htmltext = replaceSymbol(htmltext, "Cell3", c3);
		}
		if ((turned & 8) == 0)
		{
			htmltext = htmltext.replace("FontColor4", "FFFF00");
			htmltext = htmltext.replace("Cell4", "?");
		}
		else
		{
			htmltext = htmltext.replace("FontColor4", "FF6F6F");
			htmltext = replaceSymbol(htmltext, "Cell4", c4);
		}
		if ((turned & 16) == 0)
		{
			htmltext = htmltext.replace("FontColor5", "FFFF00");
			htmltext = htmltext.replace("Cell5", "?");
		}
		else
		{
			htmltext = htmltext.replace("FontColor5", "FF6F6F");
			htmltext = replaceSymbol(htmltext, "Cell5", c5);
		}
		return htmltext;
	}
	
	private static final String[] CARD_SYMBOLS = {"ERROR", "!", "=", "T", "V", "O", "P", "S", "E", "H", "A", "R", "D", "I", "N"};
	private static String replaceSymbol(String htmltext, String target, int var)
	{
		final String replacement = CARD_SYMBOLS[var <= 14 ? var : 0];
		return htmltext.replace(target, replacement);
	}
	
	@Override
	public String onTalk(L2Npc npc, L2PcInstance player)
	{
		final QuestState st = player.getQuestState(getName());
		String htmltext = getNoQuestMsg(player);
		if (st == null)
		{
			return htmltext;
		}
		
		switch (st.getState())
		{
			case State.CREATED:
			{
				htmltext = player.getLevel() < MIN_LEVEL ? "30845-02.html" : "30845-01.htm";
				break;
			}
			case State.STARTED:
			{
				if (st.getInt("ex") != 0)
				{
					// カードゲームの途中でウインドウを閉じてしまったとき
					htmltext = replaceCardsHtml(getHtm(player.getHtmlPrefix(), "30845-11a.html"), st.getInt("ex"));
				}
				else
				{
					htmltext = st.getQuestItemsCount(RED_GEM) < REQUIRED_CHIP_COUNT ? "30845-04.html" : "30845-05.html";
				}
				break;
			}
			case State.COMPLETED:
			{
				htmltext = getAlreadyCompletedMsg(player);
				break;
			}
		}
		return htmltext;
	}
	
	@Override
	public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
	{
		final L2PcInstance player;
		if (killer.isInParty())
		{
			final ArrayList<L2PcInstance> players = new ArrayList<>(11);
			players.add(killer);
			players.add(killer);
			for (L2PcInstance member : killer.getParty().getMembers())
			{
				if (member.getQuestState(getName()) != null)
				{
					players.add(member);
				}
			}
			player = players.get(Rnd.get(players.size()));
		}
		else
		{
			player = killer;
		}
		
		if ((player != null) && Util.checkIfInRange(1500, npc, player, false))
		{
			if (MONSTERS.get(npc.getId()) < getRandom(1000))
			{
				final QuestState st = player.getQuestState(getName());
				if (st != null)
				{
					st.giveItems(RED_GEM, 1);
					playSound(player, QuestSound.ITEMSOUND_QUEST_ITEMGET);
				}
			}
		}
		return super.onKill(npc, killer, isSummon);
	}
	
	public static void main(String[] args)
	{
		new Q00662_AGameOfCards(662, Q00662_AGameOfCards.class.getSimpleName(), "カード ゲームをしよう");
	}
}
