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

import java.io.*;
import java.net.*;
import javax.swing.*;

public class PutFiles extends Command
{
	PutDialog view;
	protected DataOutputStream outStream;
	DirTreeNode CDRootNode;
	int sessionSize;
	int bytesTransmitted;

	public PutFiles(DirTreeNode CDRootNode, int sessionSize)
	{
		view = new PutDialog();
		outStream = CDcreator.outStream;
		this.CDRootNode = CDRootNode;
		this.sessionSize = sessionSize;
		bytesTransmitted = 0;
	}

	private void copy(FileInputStream inFile, long bytesToWrite)
			throws java.io.IOException {
		try {
			int count = bytesTransmitted;
			while (bytesToWrite > 0) {
				byte bs[] = new byte[16*1024];
				int len = inFile.read(bs);
				if (len == -1)
					break;
				if (len > bytesToWrite)
					len = (int)bytesToWrite;
				outStream.write(bs, 0, len);
				bytesToWrite -= len;
				count += len;
				view.setProgress(count);
			}
		} finally {
			while (bytesToWrite-- > 0)
				outStream.write(0);
		}
	}

	protected void putFile(String dirName, DirTreeNode node)
		throws java.io.IOException, CommandError
	{
		File file = node.getFile();
		String fileName = dirName + "/" + node.toString();
		Version.showDebugInfo(1, fileName + " " + file);
		view.setMessage(fileName);

		if (file instanceof ServerFile)
			outStream.writeBytes("linkFile "
				+ spaceToEsc(file.getPath()) + " "
				+ spaceToEsc(fileName) + "\n");
		else
		{
			long bytesToWrite = file.length();
			FileInputStream inFile = null;
			try {
				if (bytesToWrite > 0)
					inFile = new FileInputStream(file);
			} catch (java.io.IOException e) {
				System.out.println("cannot read " + file);
				Log.put(e.toString());
				return;
			}

			outStream.writeBytes("putFile "
				+ spaceToEsc(fileName) + " "
				+ bytesToWrite + " "
				+ "444 "
				+ file.lastModified() / 1000
				+ "\n");

			copy(inFile, bytesToWrite);
		}

		readResult();
		if (!lastResultOK())
			throw new CommandError();

		if (file.length() > 0)
			bytesTransmitted +=
				1024 * ((file.length() - 1) / 1024 + 1);
		view.setProgress(bytesTransmitted);
		State.numOfFiles++;

		if (node == MainWin.bootImageNode)
			Options.bootImage = fileName;
	}

	void putTree(String dirName, DirTreeNode node)
		throws java.io.IOException, CommandError
	{
		String dirName2;
		if (dirName.equals("/"))
			dirName2 = "";
		else
			dirName2 = dirName + '/' + node.toString();

		File dir = node.getFile();
		if (dir instanceof ServerFile)
		{
			// just make a link to the file on the server
			outStream.writeBytes("linkFile "
				+ spaceToEsc(dir.getPath()) + " "
				+ spaceToEsc(dirName2) + "\n");
			readResult();
			if (!lastResultOK())
				throw new CommandError();
			return;
		}

		// transfer the files and directories contained
		// in this directory
		for (int i = 0; i < node.getChildCount(); i++)
		{
			if (cancel)
				return;
			DirTreeNode child =
				(DirTreeNode)node.getChildAt(i);
			if (child.isLeaf())
				putFile(dirName2, child);
			else
				putTree(dirName2, child);
		}

		if (dir != null && dirName2.length() != 0)
			// create the directory and set the modification time
			execCommand("mkdir "
				+ spaceToEsc(dirName2) + " "
				+ "444 "
				+ dir.lastModified() / 1000);
	}

	public void run()
	{
//		System.out.println("PutFiles");
		view.setTitle(i18n("titlePutFiles"));
		view.setRange(0, sessionSize);
		showDialog(view);

		// for netscape
		if (CDcreator.isNetscapeVM())
		try {
			netscape.security.PrivilegeManager
				.enablePrivilege("UniversalFileRead");
		}
		catch (Exception e) {
		}

		boolean error = false;
		try
		{
			putTree("/", CDRootNode);
		}
		catch (java.io.IOException e)
		{
			System.out.println("PutFiles: IOException");
		}
		catch (CommandError cmdErr)
		{
			error = true;
		}

		hideDialog();
		if (error)
			showInfoWin(new JOptionPane(
				lastResult,
				JOptionPane.INFORMATION_MESSAGE,
				JOptionPane.DEFAULT_OPTION,
				null, okButton).createDialog(
				CDcreator.mainWin, i18n("error")));

		super.run();
//		System.out.println("PutFiles end");
	}
}
