/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.editors.layout.gle2;

import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;

import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.TransferData;

import java.io.UnsupportedEncodingException;

/**
 * A d'n'd {@link Transfer} class that can transfer a <em>simplified</em> XML fragment
 * to transfer elements and their attributes between {@link LayoutCanvas}.
 * <p/>
 * The implementation is based on the {@link ByteArrayTransfer} and what we transfer
 * is text with the following fixed format:
 * <p/>
 * <pre>
 * {element-name element-property ...
 *  attrib_name="attrib_value"
 *  attrib2="..."
 *  {...inner elements...
 *  }
 * }
 * {...next element...
 * }
 *
 * </pre>
 * The format has nothing to do with XML per se, except for the fact that the
 * transfered content represents XML elements and XML attributes.
 *
 * <p/>
 * The detailed syntax is:
 * <pre>
 * - ELEMENT     := {NAME PROPERTY*\nATTRIB_LINE*ELEMENT*}\n
 * - PROPERTY    := $[A-Z]=[^ ]*
 * - NAME        := [^\n=]+
 * - ATTRIB_LINE := @URI:NAME=[^\n]*\n
 * </pre>
 *
 * Elements are represented by {@link SimpleElement}s and their attributes by
 * {@link SimpleAttribute}s, all of which have very specific properties that are
 * specifically limited to our needs for drag'n'drop.
 */
final class SimpleXmlTransfer extends ByteArrayTransfer {

    // Reference: http://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html

    private static final String TYPE_NAME = "android.ADT.simple.xml.transfer.1";    //$NON-NLS-1$
    private static final int TYPE_ID = registerType(TYPE_NAME);
    private static final SimpleXmlTransfer sInstance = new SimpleXmlTransfer();

    /** Private constructor. Use {@link #getInstance()} to retrieve the singleton instance. */
    private SimpleXmlTransfer() {
        // pass
    }

    /** Returns the singleton instance. */
    public static SimpleXmlTransfer getInstance() {
        return sInstance;
    }

    /**
     * Helper method that returns the FQCN transfered for the given {@link ElementDescriptor}.
     * <p/>
     * If the descriptor is a {@link ViewElementDescriptor}, the transfered data is the FQCN
     * of the Android View class represented (e.g. "android.widget.Button").
     * For any other non-null descriptor, the XML name is used.
     * Otherwise it is null.
     *
     * @param desc The {@link ElementDescriptor} to transfer.
     * @return The FQCN, XML name or null.
     */
    public static String getFqcn(ElementDescriptor desc) {
        if (desc instanceof ViewElementDescriptor) {
            return ((ViewElementDescriptor) desc).getFullClassName();
        } else if (desc != null) {
            return desc.getXmlName();
        }

        return null;
    }

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

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

    /** Transforms a array of {@link SimpleElement} into a native data transfer. */
    @Override
    protected void javaToNative(Object object, TransferData transferData) {
        if (object == null || !(object instanceof SimpleElement[])) {
            return;
        }

        if (isSupportedType(transferData)) {
            StringBuilder sb = new StringBuilder();
            for (SimpleElement e : (SimpleElement[]) object) {
                sb.append(e.toString());
            }
            String data = sb.toString();

            try {
                byte[] buf = data.getBytes("UTF-8");  //$NON-NLS-1$
                super.javaToNative(buf, transferData);
            } catch (UnsupportedEncodingException e) {
                // unlikely; ignore
            }
        }
    }

    /**
     * Recreates an array of {@link SimpleElement} from a native data transfer.
     *
     * @return An array of {@link SimpleElement} or null. The array may be empty.
     */
    @Override
    protected Object nativeToJava(TransferData transferData) {
        if (isSupportedType(transferData)) {
            byte[] buf = (byte[]) super.nativeToJava(transferData);
            if (buf != null && buf.length > 0) {
                try {
                    String s = new String(buf, "UTF-8"); //$NON-NLS-1$
                    return SimpleElement.parseString(s);
                } catch (UnsupportedEncodingException e) {
                    // unlikely to happen, but still possible
                }
            }
        }

        return null;
    }
}
