/*******************************************************************************
 * <copyright>
 *
 * Copyright (c) 2005, 2010 SAP AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    SAP AG - initial API, implementation and documentation
 *
 * </copyright>
 *
 *******************************************************************************/
package org.eclipse.graphiti.ui.internal.util.clipboard;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.emf.common.util.URI;
import org.eclipse.graphiti.internal.util.T;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;

/**
 * SWT {@link Transfer} for transporting a number of object {@link URI}
 * -addressable objects. Expected data class is {@link UriTransferData}. In
 * copy/paste scenario, use the {@link ModelClipboard} facility.
 * 
 * @noinstantiate This class is not intended to be instantiated by clients.
 * @noextend This class is not intended to be subclassed by clients.
 */
public class UriTransfer extends ByteArrayTransfer {

	private static final String TYPE_NAME = "URI-transfer-format"; //$NON-NLS-1$
	private static final int TYPE_ID = registerType(UriTransfer.TYPE_NAME);
	private static final String URI_SEP = "#?#"; //$NON-NLS-1$
	private static final String CHARSET = "UTF-8"; //$NON-NLS-1$

	private static final UriTransfer INSTANCE = new UriTransfer();

	/**
	 * @return the singleton instance
	 */
	public static UriTransfer getInstance() {
		return UriTransfer.INSTANCE;
	}

	@Override
	protected int[] getTypeIds() {
		return new int[] { UriTransfer.TYPE_ID };
	}

	@Override
	protected String[] getTypeNames() {
		return new String[] { UriTransfer.TYPE_NAME };
	}

	@Override
	protected void javaToNative(final Object data, final TransferData transferData) {
		if (data == null) {
			return;
		}
		final UriTransferData realData = (UriTransferData) data;
		if (realData.getUriStrings().isEmpty()) {
			return;
		}
		final ByteArrayOutputStream out = new ByteArrayOutputStream();
		final DataOutputStream dataOut = new DataOutputStream(out);
		try {
			final byte[] bytes = toTransferBytes(realData.getUriStrings());
			dataOut.writeInt(bytes.length);
			dataOut.write(bytes);
			super.javaToNative(out.toByteArray(), transferData);
		} catch (final IOException e) {
			T.racer().error("Error when writing transfer data", e); //$NON-NLS-1$
		} finally {
			try {
				dataOut.close();
				out.close();
			} catch (final IOException e) { // $JL-EXC$
			}
		}
	}

	@Override
	protected Object nativeToJava(final TransferData transferData) {
		ByteArrayInputStream in = null;
		DataInputStream dataIn = null;

		try {
			final byte[] bytes = (byte[]) super.nativeToJava(transferData);
			if (bytes == null || bytes.length == 0) {
				return null;
			}
			in = new ByteArrayInputStream(bytes);
			dataIn = new DataInputStream(in);
			final int len = dataIn.readInt();
			final byte[] uriBytes = new byte[len];
			dataIn.readFully(uriBytes);
			final List<String> uriStrings = fromTransferBytes(uriBytes);
			return new UriTransferData(uriStrings);
		} catch (final IOException e) {
			T.racer().error("Error when writing transfer data", e); //$NON-NLS-1$
			return null;
		} finally {
			try {
				if (in != null) {
					in.close();
					dataIn.close();
				}
			} catch (final IOException e) {
				//UriTransfer.sTracer.error("Error while reading stream", e); //$NON-NLS-1$
			}
		}
	}

	private byte[] toTransferBytes(final List<String> uriStrings) throws IOException {
		final StringBuilder b = new StringBuilder();
		for (final Iterator<String> iter = uriStrings.iterator(); iter.hasNext();) {
			final String s = iter.next();
			b.append(s);
			if (iter.hasNext()) {
				b.append(UriTransfer.URI_SEP);
			}
		}
		return b.toString().getBytes(UriTransfer.CHARSET);
	}

	private List<String> fromTransferBytes(final byte[] bytes) throws IOException {
		final String all = new String(bytes, UriTransfer.CHARSET);
		final String[] parts = all.split(Pattern.quote(UriTransfer.URI_SEP));
		return Arrays.asList(parts);
	}

	@Override
	public String toString() {
		return UriTransfer.TYPE_NAME;
	}

	private UriTransfer() {
	}
}