package kamicharserver;

import java.io.*;

import java.net.URL;
import java.net.URLConnection;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.dom.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.SAXException;
import org.w3c.dom.*;

public abstract class KamiWorldSave {

    public static void saveHome(String host, String map, String user, int link) {

	try {

	    String sPath = user.substring(0,1).toLowerCase()+"/"+user;
	    String sUserMap = sPath+"/default.map";
	    int x = 0;
	    int y = 0;
	    int w = 0;
	    int h = 0;
	    
	    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
	    docBuilderFactory.setIgnoringElementContentWhitespace(true);
	    docBuilderFactory.setValidating(false);
	    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

	    //
	    //Reading map with house link
	    String target = "http://" + host + "/" + map;
	    org.w3c.dom.Document doc = docBuilder.parse(target.toString());

	    Node n = doc.getDocumentElement().getElementsByTagName("linklayer").item(0).getFirstChild();
	    NodeList nlLinks = null;
	    if (n.getNodeType() == Node.TEXT_NODE) {
		nlLinks = n.getNextSibling().getChildNodes();
	    } else {
		nlLinks = n.getChildNodes();
	    }

	    //
	    //Changing
	    int l = nlLinks.getLength();
	    if (l < 1) {
		return;
	    }
	    int i = nlLinks.item(0).getNodeType() == Node.TEXT_NODE ? 1 : 0;
	    do {
		if( nlLinks.item(i).getNodeType() != Node.TEXT_NODE) {
		    //String sL = nlLinks.item(i).getAttributes().getNamedItem("id").getNodeValue();
		   // System.out.print(sL);
		    if( Integer.parseInt(nlLinks.item(i).getAttributes().getNamedItem("id").getNodeValue())==link ) {
			nlLinks.item(i).getAttributes().getNamedItem("map").setNodeValue(sUserMap);
			x = Integer.parseInt( nlLinks.item(i).getAttributes().getNamedItem("x").getNodeValue() );
			y = Integer.parseInt( nlLinks.item(i).getAttributes().getNamedItem("y").getNodeValue() );
			w = Integer.parseInt( nlLinks.item(i).getAttributes().getNamedItem("width").getNodeValue() );
			h = Integer.parseInt( nlLinks.item(i).getAttributes().getNamedItem("height").getNodeValue() );
			break;
		    }
		   
		}
		++i;
	    } while(i<l);

	    sPath = map.substring(0, map.lastIndexOf('/')+1);
	    saveFile(host, xmlToString(doc), sPath, map.substring(map.lastIndexOf('/')+1));
	    //saveFile(host, doc.toString(), sPath+"/", "default.map");
	    
	    //
	    //Reading default.map
	    target = "http://" + host + "/" + sUserMap;
	    doc = docBuilder.parse(target.toString());

	    n = doc.getDocumentElement().getElementsByTagName("linklayer").item(0).getFirstChild();
	    nlLinks = null;
	    if (n.getNodeType() == Node.TEXT_NODE) {
		nlLinks = n.getNextSibling().getChildNodes();
	    } else {
		nlLinks = n.getChildNodes();
	    }

	    //
	    //Changing
	    l = nlLinks.getLength();
	    if (l < 1) {
		return;
	    }
	    i = nlLinks.item(0).getNodeType() == Node.TEXT_NODE ? 1 : 0;
	    do {
		if( nlLinks.item(i).getNodeType() != Node.TEXT_NODE) {
		    if( nlLinks.item(i).getAttributes().getNamedItem("type").getNodeValue().equals("locked") ) {
			nlLinks.item(i).getAttributes().getNamedItem("map").setNodeValue(map);
			nlLinks.item(i).getAttributes().getNamedItem("nx").setNodeValue(""+((int)(x+Math.floor(w/2))));
			nlLinks.item(i).getAttributes().getNamedItem("ny").setNodeValue(""+(h+y+30));
			break;
		    }
		}
		++i;
	    } while(i<l);

	    sPath = user.substring(0,1).toLowerCase()+"/"+user;
	    saveFile(host, xmlToString(doc), sPath+"/", "default.map");

	} catch (SAXException ex) {
	    Logger.getLogger(KamiWorldSave.class.getName()).log(Level.SEVERE, null, ex);
	} catch (ParserConfigurationException ex) {
	    Logger.getLogger(KamiWorldSave.class.getName()).log(Level.SEVERE, null, ex);
	} catch (UnsupportedEncodingException ex) {
	    ex.printStackTrace();
	} catch (IOException ex) {
	    System.out.println("Unable to load maps listing.");
	}

    }
    
    public static void saveFile(String host, String data, String path, String name) {
	
	try {
	    // Saving
	    URL uURL = new URL("http://" + host + "/mapsave.php");
	    URLConnection ucConnection = uURL.openConnection();

	    // sending POST data
	    ucConnection.setDoOutput(true);
	    OutputStreamWriter wr = new OutputStreamWriter(ucConnection.getOutputStream());
	    wr.write(java.net.URLEncoder.encode("userid", "UTF-8") + "=" + java.net.URLEncoder.encode("2", "UTF-8")+"&"
		    +java.net.URLEncoder.encode("mapname", "UTF-8") + "=" + java.net.URLEncoder.encode(name, "UTF-8")+"&"
		    +java.net.URLEncoder.encode("path", "UTF-8") + "=" + java.net.URLEncoder.encode(path, "UTF-8")+"&"
		    +java.net.URLEncoder.encode("mapdata", "UTF-8") + "=" + java.net.URLEncoder.encode(data, "UTF-8"));
	    wr.flush();
	    wr.close();

	    // getting results
	    BufferedReader br = new BufferedReader(new InputStreamReader(ucConnection.getInputStream()));

	    StringBuilder sDoc = new StringBuilder();
	    String sLine;
	    while ((sLine = br.readLine()) != null) {
		sDoc.append(sLine);
	    }
	    
	    int i1 = sDoc.indexOf("save=");
	    int i2 = sDoc.indexOf("#end#");

	    System.out.println(sDoc.substring(i1+5, i2));
	    
	} catch (UnsupportedEncodingException ex) {
	    ex.printStackTrace();
	} catch (IOException ex) {
	    System.out.println("Unable to load maps listing.");
	}
    }
    
    public static String xmlToString(org.w3c.dom.Document doc) {
	try {
	    Source source = new DOMSource(doc);
	    StringWriter sw = new StringWriter();
	    StreamResult result = new StreamResult(sw);

	    // Write the DOM document to the file
	    Transformer xformer = TransformerFactory.newInstance().newTransformer();
	    xformer.transform(source, result);

	    return sw.toString();
	} catch (TransformerException ex) {
	    Logger.getLogger(KamiWorldSave.class.getName()).log(Level.SEVERE, null, ex);
	}
	return null;
    }
}
