package org.eclipse.swt.net;

import java.io.*;

import sun.misc.*;

public class ResourceEncoderUtil {
	static String sourceFolder;
	
	static final String base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	
	public static void main (String[] args) throws Exception {
		writeToFile(args);
	}
	
	/**
	 * {
	 * @param fileName Name of JS file without extension
	 * @param args list of resource file paths to encode
	 * @throws Exception
	 */
	static void writeToFile(String[] args)throws Exception {
		String fileName = args[0];
		String resourceName = fileName;
		int index = resourceName.lastIndexOf(File.separatorChar);
		if (index != -1) resourceName = resourceName.substring(index + 1);
		index = resourceName.lastIndexOf('.');
		if (index != -1) resourceName = resourceName.substring(0, index);
		StringBuffer resourceFile = new StringBuffer();
		String newLine = System.getProperty("line.separator");
		sourceFolder = args[1];
		resourceFile.append("if(typeof ");
		resourceFile.append(resourceName); 
		resourceFile.append(" == \"undefined\"){");
		resourceFile.append(newLine);
		resourceFile.append("(function(){");
		resourceFile.append(newLine);
		resourceFile.append("if(typeof this[\"");
		resourceFile.append(resourceName);
		resourceFile.append("\"] == \"undefined\"){");
		resourceFile.append(newLine);
		resourceFile.append("\t");
		resourceFile.append("this.");
		resourceFile.append(resourceName);
		resourceFile.append(" = {};");
		resourceFile.append(newLine);
		resourceFile.append("}");
		resourceFile.append(newLine);
		resourceFile.append(newLine);


		for (int i=2; i<args.length; i++) {
			FileInputStream reader = new FileInputStream(sourceFolder+args[i]);
			 String packagePath = args[i].replace(File.separatorChar, '_');
			 packagePath = packagePath.replace('.', '_');
			 resourceFile.append(packagePath);
			 resourceFile.append(" = \"");
			 byte[] tempBytes = new byte[reader.available()];
			 int read = 0, offset = 0;
			 while ((read = reader.read(tempBytes, offset, tempBytes.length - offset))!= -1) {
				 offset += read;
				 if (read == tempBytes.length) break;
			 }
			 String encodedString = encode(tempBytes);
			 resourceFile.append(encodedString);
			 resourceFile.append("\";");
			 resourceFile.append(newLine);
			 resourceFile.append(newLine);
			 reader.close();
		}
		
		resourceFile.append(newLine);
		resourceFile.append("})();");
		resourceFile.append(newLine);
		resourceFile.append("}");
		resourceFile.append(newLine);

		File file = new File(fileName);
		FileOutputStream os = new FileOutputStream(file);
		os.write(resourceFile.toString().getBytes());
		os.close();
	}
	
	static StringBuffer removeNewLines(StringBuffer buffer) {
		StringBuffer tempBuffer = new StringBuffer();
		for (int i=0; i<buffer.length(); i++) {
			if (buffer.charAt(i) != '\n' && buffer.charAt(i) != '\r') {
				tempBuffer.append(buffer.charAt(i));
			} 
		}
		return tempBuffer;
	}
	
	
	static public String encode(byte[] buffer){
		StringBuffer resultBuffer = new StringBuffer();
		int count = 2;
		for (int i=0; i<buffer.length; i+=3) {
			int c = (buffer[i] & 0xFF) << 16;
			count = 2;
			if (i+1 < buffer.length) {
				count++;
				c |= (buffer[i+1]& 0xFF)  << 8;
			}
			if (i+2 < buffer.length) {
				count++;
				c |= buffer[i+2] & 0xFF;
			}
			
			resultBuffer.append(base64Table.charAt((c >> 18) & 0x3F));
			resultBuffer.append(base64Table.charAt((c >> 12) & 0x3F));
			if (count >= 3) {
				resultBuffer.append(base64Table.charAt((c >> 6) & 0x3F));
			}
			if (count == 4) {
				resultBuffer.append(base64Table.charAt((c >> 0) & 0x3F));
			}
			
		}
		if (count==3) {
			resultBuffer.append('=');	
		} else if (count ==2) {
			resultBuffer.append('=');
			resultBuffer.append('=');	
		} 
		
		return resultBuffer.toString();
	}
	
}
