/**
 * 
 *	
 * Copyright (C) 2003 PlaneShift Team (info@planeshift.it, 
 * http://www.planeshift.it)
 *
 * Author: Luca Pancallo <pancallo@netscape.net>
 *
 * 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 (version 2 of the License)
 * 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.
 *
 *
 * Version 1
 */

import java.util.*;
import java.io.*;

public class LevMerge
{

    static boolean DEBUG = false;

    public static void main (String args [])
    {

        if (args.length < 1) {
            System.err.println ("Usage: java LevMerge <file1> <file2> <...>");
            System.exit (1);
        }


        try {
            // count files
            int fileNum = args.length;
            
            // open destination file
            File dest = new File("world");
            PrintWriter destOut = new PrintWriter(new FileOutputStream(dest));
            // open first file
            File source1 = new File(args[0]);
            BufferedReader source1Buf = new BufferedReader(new FileReader(source1));

            // write once till <textures>
            String line = source1Buf.readLine();
            while ( line!=null ) {
                // write to output
                destOut.println(line);
                // read next line
                line = source1Buf.readLine();

                if (line.indexOf("<textures>")!=-1)
                    break;
            }

            // close source
            source1Buf.close();

            // merge all <textures> no duplicates
            System.out.print("Writing textures...");
            mergeNoDuplicates("<textures>","</textures>",destOut,args);
            System.out.println("done");

            // merge all <materials> no duplicates
            System.out.print("Writing materials...");
            mergeNoDuplicates("<materials>","</materials>",destOut,args);
            System.out.println("done");

            // merge all <plugins> (remove duplicates?)
            System.out.print("Writing plugins...");
            mergeNoDuplicates("<plugins>","</plugins>",destOut,args);
            System.out.println("done");

            // sequentially write all <meshfact>s
            System.out.print("Writing meshfacts...");
            writeSequentially("<meshfact","</meshfact>",destOut,args);
            System.out.println("done");

            // write once <settings> (first file used)
            System.out.print("Writing settings...");
            writeOnce("<settings>","</settings>",destOut,args);
            System.out.println("done");

            // sequentially write all <sector>s
            System.out.print("Writing sectors...");
            writeSequentially("<sector name","</sector>",destOut,args);
            System.out.println("done");

            // write just one <start> (first file used)
            System.out.print("Writing start position...");
            writeOnce("<start name","</start>",destOut,args);
            System.out.println("done");

            // merge all <sequences>
            System.out.print("Writing sequences...");
            destOut.println("<sequences>");
            writeSequentially("<sequence name","</sequence>",destOut,args);
            destOut.println("</sequences>");
            System.out.println("done");

            // merge all <triggers>
            System.out.print("Writing triggers...");
            destOut.println("<triggers>");
            writeSequentially("<trigger name","</trigger>",destOut,args);
            destOut.println("</triggers>");
            System.out.println("done");

            // write end world
            destOut.println("</world>");

            // close destination
            destOut.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }


    static void mergeNoDuplicates (String startTag, String endTag, PrintWriter destOut, String[] args) throws Exception {

            int fileNum = args.length;

            destOut.println(startTag);
            Vector text = new Vector();
            for (int i=0; i<fileNum; i++) {
                // open file
                File source = new File(args[i]);
                BufferedReader sourceBuf = new BufferedReader(new FileReader(source));
                if (sourceBuf==null) {
                    System.out.println("File null"+args[i]);
                    break;
                }

                // seek startTag
                String line = sourceBuf.readLine().trim();
                
                while (line.indexOf(startTag)==-1) {
                    line = sourceBuf.readLine();
                }

                // add lines in vector removing duplicates
                while (true) {
                    line = sourceBuf.readLine();
                    if (line.indexOf(endTag)==-1) {
                        // search if present
                        boolean found = false;
                        for (int k=0;k<text.size();k++) {
                            if (((String)text.elementAt(k)).trim().equals(line.trim()))
                                found=true;
                        }    
                        if (!found)
                            text.addElement(line.trim());
                    } else
                        break;
                }
                
                // close file
                sourceBuf.close();
            }
            // write lines
            for (int i=0; i<text.size(); i++) {
                destOut.println(text.elementAt(i));
            }
            destOut.println(endTag);
    }

    static void writeSequentially (String startTag, String endTag, PrintWriter destOut, String[] args) throws Exception {

        int fileNum = args.length;

        Vector text = new Vector();
        for (int i=0; i<fileNum; i++) {

            // open file
            File source = new File(args[i]);
            BufferedReader sourceBuf = new BufferedReader(new FileReader(source));
            if (sourceBuf==null) {
                System.out.println("File null"+args[i]);
                break;
            }
            if (DEBUG) System.out.println("Working on file: "+args[i]);

            boolean insideTag=false;

            String line = sourceBuf.readLine().trim();

            // write lines
            while (line!=null) {

                // seek startTag (avoid sector inside portal or start tags)
                if ((line.indexOf(startTag)!=-1 && line.indexOf("<portal>")==-1 && line.indexOf("<start name")==-1) || 
                    (line.indexOf(startTag)!=-1 && line.indexOf("<sector>")==-1 && line.indexOf("</sector>")==-1 ))
                {   

                    if (DEBUG) System.out.println("Found startTag: "+startTag);
                    insideTag=true;
                    // search duplicates on special lines
                    if (line.indexOf("<meshfact")!=-1 && line.indexOf("/meshfact>")!=-1)
                    {
                        // search if present
                        boolean found = false;
                        for (int k=0;k<text.size();k++) {
                            if (((String)text.elementAt(k)).trim().equals(line.trim()))
                                found=true;
                        }
                        if (!found) {
                            destOut.println(line);
                            text.addElement(line.trim());
                        }
                        line = sourceBuf.readLine();
                        insideTag=false;
                        continue;
                    }

                    // if end tag on same line
                    if (line.indexOf(endTag)!=-1 && line.indexOf("</portal>")==-1 && line.indexOf("</start>")==-1) {
                        if (DEBUG) System.out.println("Found endTag same line: "+endTag);
                        destOut.println(line);
                        line = sourceBuf.readLine();
                        insideTag=false;
                        continue;
                    }
                }

                // seek end tag skip sector inside portal
                if (line.indexOf(endTag)!=-1 && line.indexOf("</portal>")==-1 && line.indexOf("</start>")==-1 && line.indexOf("<sector>")==-1 )
                {
                    if (DEBUG) System.out.println("Found endTag: "+endTag);
                    destOut.println(line); // print closing tag
                    insideTag=false;
                }

                // write lines
                if (insideTag)
                    destOut.println(line);

                // move to next line
                line = sourceBuf.readLine();
            }

            // close file
            sourceBuf.close();
        }
    }

    static void writeOnce (String startTag, String endTag, PrintWriter destOut, String[] args) throws Exception {

        // use first file
        File source = new File(args[0]);
        BufferedReader sourceBuf = new BufferedReader(new FileReader(source));
        if (sourceBuf==null) {
            System.out.println("File null"+args[0]);
            return;
        }

        // seek startTag
        String line = sourceBuf.readLine().trim();

        while (line.indexOf(startTag)==-1) {
            line = sourceBuf.readLine();
        }

        // end in same line
        if (line.indexOf(endTag)!=-1) {
            destOut.println(line);
            sourceBuf.close();
            return;
        }
        
        // do something for other case
        // TODO
    }

}
