package com.gamizi.util;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Xml ÆÄ½Ì°ü·Ã Å¬·¡½º
 * @author Å¥¾Ø¼Öºê : °­¼ºÇö
 *
 */
public class XmlUtil {
	public XmlUtil(){
	}
	/**
	 * xml ÆÄÀÐÀ» ÀÐ¾îµé¿© document ¸¦ »ý¼ºÇÑ´Ù.
	 * @param filePath ÆÄÀÏ °æ·Î
	 * @param fileName ÆÄÀÏ¸í
	 * @return
	 * @throws Exception
	 */
	public Document parse(String filePath, String fileName) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();	
		DocumentBuilder builder = factory.newDocumentBuilder();
		factory.setNamespaceAware( true );
		factory.setValidating( true );
		Document doc = builder.parse(new File(filePath+fileName));
		return doc;
	}
	
	/**
	 * ¼Ò½ºÀÇ Element·Î ºÎÅÍ key¿¡ ÇØ´çÇÏ´Â ÀÚ½Änode¸¦ Element·Î ÇüÀüÈ¯ÇÏ¿© ¹ÝÈ¯ÇÑ´Ù.
	 * @param srcElement Á¶È¸¸¦ ¿øÇÏ´Â element
	 * @param key ÀÚ½Ä ·Îµå element
	 * @return
	 */
	public Element getElement(Element srcElement, String key){
		Element retEle = null;
		NodeList ddNodeList = srcElement.getChildNodes();
		for(int i = 0 ; i < ddNodeList.getLength() ; i++){
			Node node =srcElement.getChildNodes().item(i);
			String nodeName = node.getNodeName();
			
			if(key.equals(nodeName)){
				retEle = (Element)node;
			}
		}
		return retEle;
	}
	

	/**
	 * Element¸¦ Ãß°¡ÇÑ´Ù.
	 * 
	 * @param srcElement Ãß°¡¸¦ ¿øÇÏ´Â ¼Ò½ºÀÇ element
	 * @param document //document 
	 * @param elementName //Ãß°¡¸¦ ¿øÇÏ´Â element ÀÌ¸§
	 * @param removeFlag //±âÁ¸¿¡ elementName À¯¹«¿¡ µû¶ó YÀÌ¸é »èÁ¦, NÀÌ¸é element °è¼Ó Ãß°¡.
	 */
	public void addElement(Element srcElement, Document document, String elementName, 
			boolean removeFlag){

		if(removeFlag){
			//»èÁ¦ÇÒ element¸¦ Ã£´Â´Ù.
			//Á¶È¸ÇÒ element¿¡ element°¡ ¾ø´Ù¸é nullÀ» ¸®ÅÏ
			Element removeElement = getElement(srcElement,elementName);
			if(removeElement!=null){
				removeElement(srcElement,removeElement);	
			}
		}
		Element addElement = document.createElement(elementName);
		srcElement.appendChild(addElement);
		//
	}

	/**
	 * parentsElements ¿¡ elementNameÀ¸·Î element¸¦ Ãß°¡ ÈÄ
	 * key¿Í value¸¦ ÀÌ¿ëÇÏ¿© attribute¸¦ Ãß°¡ÇÑ´Ù.
	 * removeFlag¸¦ ÀÌ¿ëÇÏ¿© YÀÌ¸é ±âÁ¸¿¡ elementName ÀÖÀ¸¸é ÇØ´ç element¸¦ »èÁ¦ÇÑ´Ù.
	 * @param parentsElements
	 * @param document
	 * @param elementName
	 * @param key
	 * @param value
	 * @param removeFlag
	 */
	public void addElementAttribute(Element parentsElements, Document document, String elementName, 
			String key, String value, boolean removeFlag){
		addElement(parentsElements,document,elementName,removeFlag);
		addAttribute(getElement(parentsElements,elementName),key, value);
		
	}
	
	/**
	 * ¼Ò½ºÀÇ ¿ä¼ÒÁß key°ª¿¡ ÇØ´çÇÏ´Â ¿ä¼Ò°¡ ÀÖ´ÂÁö Á¶È¸
	 * @param srcElement
	 * @param key
	 * @return
	 */
	public boolean isChildElement(Element srcElement, String key){
		boolean retFlag = false;
		NodeList ddNodeList = srcElement.getChildNodes();
		for(int i = 0 ; i < ddNodeList.getLength() ; i++){
			Node node =srcElement.getChildNodes().item(i);
			String nodeName = node.getNodeName();
			
			if(key.equals(nodeName)){
				retFlag = true;
			}
		}
		return retFlag;
	}
	
	/**
	 * 
	 * @param srcElement
	 * @param removeElement
	 */
	public void removeElement(Element srcElement, Element removeElement){
		if(isChildElement(srcElement,removeElement.getTagName()))
		srcElement.removeChild(removeElement);	
	}
	
	public void addAttribute(Element srcElement, String key, String value){
		srcElement.setAttribute(key, value);
	}	
	
	public void makeFile(Document document, String fileName, String encoding, String docTypeSystem) throws Exception{
		//..º¯È¯±â »ý¼º
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer transformer = tf.newTransformer();
		
		//..Ãâ·Â Æ÷¸Ë ¼³Á¤
		transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
		transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, docTypeSystem);
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		
		
		//..DOMSource °´Ã¼ »ý¼º
		DOMSource source = new DOMSource(document);
		
		//..StreamResult °´Ã¼ »ý¼º
		StreamResult result = new StreamResult(new File(fileName));
		
		//..ÆÄÀÏ·Î ÀúÀåÇÏ±â
		transformer.transform(source, result);		
	}
}
