package com.laytonsmith.core.functions;

import com.laytonsmith.PureUtilities.Version;
import com.laytonsmith.annotations.api;
import com.laytonsmith.core.CHVersion;
import com.laytonsmith.core.constructs.CString;
import com.laytonsmith.core.constructs.CVoid;
import com.laytonsmith.core.constructs.Construct;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.environments.Environment;
import com.laytonsmith.core.exceptions.CRE.CREFormatException;
import com.laytonsmith.core.exceptions.CRE.CREIOException;
import com.laytonsmith.core.exceptions.CRE.CREThrowable;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

/**
 *
 * @author cailin
 */
public class Clipboard {
    public static String docs() {
	return "Provides functions for managing the system clipboard";
    }

    private final static java.awt.datatransfer.Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

    @api
    public static class get_clipboard extends AbstractFunction {

	@Override
	public Class<? extends CREThrowable>[] thrown() {
	    return new Class[]{CREFormatException.class};
	}

	@Override
	public boolean isRestricted() {
	    return true;
	}

	@Override
	public Boolean runAsync() {
	    return null;
	}

	@Override
	public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
	    Cmdline.requireCmdlineMode(environment, this, t);
	    Transferable tr = clipboard.getContents(null);
	    if(tr.isDataFlavorSupported(DataFlavor.stringFlavor)) {
		try {
		    String data = (String) tr.getTransferData(DataFlavor.stringFlavor);
		    return new CString(data, t);
		} catch (UnsupportedFlavorException ex) {
		    // Can't happen
		    throw new RuntimeException(ex);
		} catch (IOException ex) {
		    throw new CREIOException(ex.getMessage(), t, ex);
		}
	    } else {
		throw new CREFormatException("Clipboard value does not support parsing as text", t);
	    }
	}

	@Override
	public String getName() {
	    return "get_clipboard";
	}

	@Override
	public Integer[] numArgs() {
	    return new Integer[]{0, 1};
	}

	@Override
	public String docs() {
	    return "string {[flavor]} Returns the contents of the system clipboard. Can only be used in cmdline mode. Flavor defaults to null, and is currently unused. Only strings are currently supported."
		    + " If a string version of the clipboard contents cannot be parsed, a FormatException is thrown.";
	}

	@Override
	public Version since() {
	    return CHVersion.V3_3_2;
	}

    }

    @api
    public static class set_clipboard extends AbstractFunction {

	@Override
	public Class<? extends CREThrowable>[] thrown() {
	    return null;
	}

	@Override
	public boolean isRestricted() {
	    return true;
	}

	@Override
	public Boolean runAsync() {
	    return null;
	}

	@Override
	public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
	    Cmdline.requireCmdlineMode(environment, this, t);
	    String data = args[0].val();
	    StringSelection s = new StringSelection(data);
	    clipboard.setContents(s, s);
	    return CVoid.VOID;
	}

	@Override
	public String getName() {
	    return "set_clipboard";
	}

	@Override
	public Integer[] numArgs() {
	    return new Integer[]{1, 2};
	}

	@Override
	public String docs() {
	    return "void {value, [flavor]} Sets the contents of the system clipboard, to the given value. Can only be used in cmdline mode. Flavor defaults to null, and is currently unused. Only strings are currently supported.";
	}

	@Override
	public Version since() {
	    return CHVersion.V3_3_2;
	}

    }
}

@@ -120,16 +120,66 @@
 ns.api;%0A
+import com.laytonsmith.annotations.noboilerplate;%0A
 import c
@@ -201,32 +201,32 @@
 core.CHVersion;%0A
-
 import com.layto
@@ -568,32 +568,111 @@
 CREIOException;%0A
+import com.laytonsmith.core.exceptions.CRE.CREInsufficientPermissionException;%0A
 import com.layto
@@ -1296,32 +1296,51 @@
 rd();%0A%0A    @api%0A
+    @noboilerplate%0A
     public stati
@@ -1499,16 +1499,58 @@
 on.class
+, CREInsufficientPermissionException.class
 %7D;%0A%09%7D%0A%0A%09
@@ -2962,24 +2962,43 @@
 %7D%0A%0A    @api%0A
+    @noboilerplate%0A
     public s
@@ -3118,35 +3118,84 @@
  %7B%0A%09    return n
-ull
+ew Class%5B%5D%7BCREInsufficientPermissionException.class%7D
 ;%0A%09%7D%0A%0A%09@Override

Fix failing unit test