package de.rico.adventure.io;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import de.rico.adventure.conversation.Branch;
import de.rico.adventure.conversation.Conversation;
import de.rico.adventure.conversation.Sentence;
import de.rico.adventure.entity.character.AbstractCharacter;
import de.rico.adventure.main.ShootOut3DMain;
import de.rico.adventure.structure.Chapter;
import de.rico.adventure.structure.Room;
import de.rico.engine.input.InputManager;

/**
 * This class can be used to read in XML style conversation files.
 * @author Frank Bruns
 *
 */
public class ConversationReader
{


	/**
	 * Reads the conversations data from the specified file.
	 * @param path filepath + name of the file to load from
	 * @param chapter chapter object to read the conversations for
	 * @param input input manager object
	 */
	public List<Conversation> readConversations(String path, Chapter chapter, InputManager input)
	{
		List<Conversation> list = new ArrayList<Conversation>();

		Document document = null;
		SAXReader reader = new SAXReader();
		reader.setEncoding("ISO-8859-1");
        try
		{
        	ShootOut3DMain.getInstance().setLoadingInfoText("Parsing conversation file");
			document = reader.read(path);
		}
		catch (DocumentException e)
		{
			System.out.println("Error while parsing file.");
			ShootOut3DMain.getInstance().setLoadingInfoText("Error while parsing conversation file");
			e.printStackTrace();
		}

		// read the information from the loaded file
		// read in data, if available
		Node baseNode = document.selectSingleNode("//conversations");

		if(baseNode != null)
		{
			List<Node> conversationNodes = baseNode.selectNodes("conversation");

			for(Node conNode : conversationNodes)
			{
				String scriptId = conNode.selectSingleNode("@scriptid").getText();

				ShootOut3DMain.getInstance().setLoadingInfoText("Loading: conversation - "+scriptId);

				Conversation con = new Conversation(scriptId,chapter,input);

				// find branches and add them
				List<Node> branchNodes = conNode.selectNodes("branch");
				for(Node branchNode : branchNodes)
				{
					String branchId = branchNode.selectSingleNode("@id").getText();
					String title = branchNode.selectSingleNode("@title").getText();
					String available = branchNode.selectSingleNode("@available").getText();

					Branch branch = new Branch(branchId,title,new Boolean(available));

					// find sentences of the branch and add them
					List<Node> sentenceNodes = branchNode.selectNodes("sentence");
					for(Node sentenceNode : sentenceNodes)
					{
						String saidBy = sentenceNode.selectSingleNode("@by").getText();
						Node scriptCodeNode = sentenceNode.selectSingleNode("@code");

						String soundFile = null;
						if(sentenceNode.selectSingleNode("@file") != null)
							soundFile = sentenceNode.selectSingleNode("@file").getText();

						// find the character that is identified by the saidBy string
						AbstractCharacter c  = null;

						// find npc to the sentence
						for(Room room : chapter.getRooms())
						{
							if(room.getCharacter(saidBy) != null)
							{
								c = room.getCharacter(saidBy);
								break;
							}
						}

						// find player to sentence
						if(saidBy.equals(chapter.getActiveRoom().getPlayer().getScriptId()))
						{
							c = chapter.getActiveRoom().getPlayer();
						}

						Sentence sent = null;
						if(soundFile == null)
							sent = new Sentence(c,sentenceNode.getText());
						else sent = new Sentence(c,sentenceNode.getText(),soundFile);

						// assign scripted code, if available
						if(scriptCodeNode != null)
							sent.setScriptCode(scriptCodeNode.getText());

						// add sentence to branch
						branch.addSentence(sent);
					}

					// add branch to conversation object
					con.addBranch(branch);
				}

				// add the conversation to the list
				list.add(con);
			}
		}
		return list;
	}
}
