/*
 * @(#)Project.java
 *
 * This file is part of webCDwriter - Network CD Writing.
 *
 * Copyright (C) 2001-2004 Jörg P. M. Haeger
 *
 * webCDwriter is free software. See CDcreator.java for details.
 */

import javax.swing.tree.*;

/**
 * A CD project.
 *
 * @version 20040302
 * @author Jörg Haeger, 24.05.2001
 */
class Project {
	public static CDNode CDRoot;
	private static Command commands[] = new Command[5];
	private static int numOfCommands = 0;
	public static int numOfFiles = 0;
	public static long size = 0, transferSize = 0;

	public static void add(CDNode node, TreePath path) {
		String prefix = "";
		if (node.getFile() instanceof ServerFile)
			prefix = "server:";
		String dest = toString(path);
		if (!dest.endsWith("/"))
			dest = dest + "/";
		append("add", prefix + node.getFile(), dest);
	}

	public static void add(String arg1, String arg2) {
		File2 file;
		if (arg1.startsWith("server:"))
			file = new ServerFile(arg1.substring(7));
		else
			file = new SecFile(arg1);

		CDNode newNode = new CDNode(file);
		getCDNode(CDRoot, arg2).insert(newNode);

		append("add", arg1, arg2);
	}

	private static void append(String type, String arg1, String arg2) {
		Version.debug("Project::append()",
			type + " " + arg1 + " " + arg2);

		while (true) {
			int p0 = arg2.indexOf("//");
			if (p0 < 0)
				break;
			arg2 = arg2.substring(0, p0) + arg2.substring(p0 + 1);
		}

		if (numOfCommands == commands.length) {
			Command[] old = commands;
			commands = new Command[numOfCommands + 100];
			for (int i = 0; i < numOfCommands; i++)
				commands[i] = old[i];
		}

		commands[numOfCommands] = new Command(type, arg1, arg2);
		numOfCommands++;
	}

	public static String getCommandArg1(int index) {
		return commands[index].arg1;
	}

	public static String getCommandArg2(int index) {
		return commands[index].arg2;
	}

	public static String getCommandType(int index) {
		return commands[index].type;
	}

	protected static CDNode getCDNode(CDNode node, String path) {
		// skip slashes
		int i = 0;
		for (; i < path.length() && path.charAt(i) == '/'; i++);
		path = path.substring(i);

		if (path.length() == 0)
			return node;

		int next = path.indexOf("/");
		if (next < 0) {
			int index = node.getIndex(path);
			if (index < 0)
				return null;
			else
				return (CDNode)node.getChildAt(index);
		}

		String s1 = path.substring(0, next);
		String s2 = path.substring(path.indexOf("/"));
//		System.out.println(s1);
//		System.out.println(s2);

		i = node.getIndex(s1);
		if (i < 0) {
			CDNode newNode = new CDNode(s1);
			node.insert(newNode);
			return getCDNode(newNode, s2);
		}
		else
			return getCDNode((CDNode)node.getChildAt(i), s2);
	}

	public static int getNumOfCommands() {
		return numOfCommands;
	}

	public static boolean isTooBig() {
		return size > 5L * 1024 * 1024 * 1024;
	}

	public static void mkdir(TreePath path) {
		append("mkdir", toString(path), "");
	}

	public static void mkdir(String arg) {
		getCDNode(CDRoot, arg + "/");
		append("mkdir", arg, "");
	}

	public static void moveDown(TreePath path) {
		append("down", toString(path), "");
	}

	public static void moveDown(String arg) {
		CDNode node = getCDNode(CDRoot, arg);
		if (node == null)
			return;
//		CDcreator.model.moveUpOrDown(node, false);
		MutableTreeNode parent = (MutableTreeNode)node.getParent();
		if (parent == null)
			return;
		int p = parent.getIndex(node);
		if (p >= 0 && p < parent.getChildCount() - 1) {
			parent.remove(p);
			parent.insert(node, p + 1);
		}
		append("down", arg, "");
	}

	public static void moveUp(TreePath path) {
		append("up", toString(path), "");
	}

	public static void moveUp(String arg) {
		CDNode node = getCDNode(CDRoot, arg);
		if (node == null)
			return;
//		CDcreator.model.moveUpOrDown(node, true);
		MutableTreeNode parent = (MutableTreeNode)node.getParent();
		if (parent == null)
			return;
		int p = parent.getIndex(node);
		if (p > 0) {
			parent.remove(p);
			parent.insert(node, p - 1);
		}
		append("up", arg, "");
	}

	public static void remove(TreePath path) {
		append("rm", toString(path), "");
	}

	public static void remove(String arg) {
		CDNode node = getCDNode(CDRoot, arg);
		if (node == null)
			return;
		node.removeFromParent();
		append("rm", arg, "");
	}

	public static void rename(TreePath path, String newName) {
		append("mv", toString(path),
			toString(path.getParentPath()) + "/" + newName);
	}

	public static void rename(String oldName, String newName) {
		CDNode node = getCDNode(CDRoot, oldName);
		if (node == null)
			return;

		int lastSlash = newName.lastIndexOf('/');
		if (lastSlash < 0)
			return;
		String str1 = newName.substring(0, lastSlash);
		String str2 = newName.substring(lastSlash + 1);

		CDNode newNode = getCDNode(CDRoot, str1);
		if (newNode == null)
			return;

		if (str2.length() == 0) {
			// mv a b/
			node.removeFromParent();
			newNode.insert(node);
		}
		else
		if (newNode.getIndex(str2) < 0) {
			// mv a b/a
			node.removeFromParent();
			node.setUserObject(str2);
			newNode.insert(node);
		}
		else
			return;

		append("mv", oldName, newName);
	}

	public static void setCDRoot(CDNode node) {
		CDRoot = node;
		numOfCommands = 0;
	}

	static String toString(TreePath path) {
		String str = "";
		for (int i = 1; i < path.getPathCount(); i++) {
			CDNode node = (CDNode)path.getPathComponent(i);
			str = str + "/" + node.toString();
		}

		if (str.length() == 0)
			return "/";
		else
			return str;
	}

	static class Command {
		public Command(String type, String arg1, String arg2) {
			this.type = type;
			this.arg1 = arg1;
			this.arg2 = arg2;
		}

		public String type;
		public String arg1, arg2;
	}
}
