package net.returnvoid.tools;

import java.applet.Applet;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import processing.core.PApplet;

/*
 * This code is copyright (c) Diana Lange 2017
 *
 * The library is published under the Creative Commons license NonCommercial 4.0.
 * Please check https://creativecommons.org/licenses/by-nc/4.0/ for more information.
 * 
 * This program is distributed in the hope that it will be useful, but without any warranty.
 */

/**
 * This class tries to provide solutions which occur when using Processing's
 * different versions. The main problem of the miscellaneous versions is that
 * some attributes and methods have changes (or their visibility).
 * 
 * @author Diana Lange
 *
 */
public class ProcessingTools {
	/**
	 * Returns the sketchPath (the absolute location of the current sketch).
	 * This needs to be called since Processing 3.0 and later uses
	 * PApplet.sketchPath() and earlier releases uses PAppler.sketchPath.
	 * 
	 * @param parent
	 *            The PApplet object.
	 * @return The path of the sketch.
	 */
	@SuppressWarnings("all")
	public static String getSketchPath(PApplet parent) {
		String path = "";
		int version = ProcessingTools.getProcessingVersion(parent);

		if (version < 3) {

			// try to access the field sketchPath and get it's value
			try {
				Field field = parent.getClass().getField("sketchPath");
				if (field.getType().equals(String.class)) {
					path = (String) field.get(parent);
				} else {
					System.err.println("Something went wrong. PApplet doesn't contain an attribut named \"sketchPath\".");
				}
			} catch (Exception e) {
				System.err.println(e);
			}
		} else {
			// try to access the method sketchPath() and get it's value
			try {
				Method method = parent.getClass().getMethod("sketchPath", null);

				if (method.getReturnType().equals(String.class)) {
					path = (String) method.invoke(parent);
				} else {
					System.err.println("Something went wrong. PApplet doesn't contain a method named \"sketchPath\".");
				}
			} catch (Exception e) {
				System.err.println(e);
			}
		}

		return path;
	}

	/**
	 * Returns the release number (1, 2, 3) of Processing for the given PApplet
	 * object.
	 * 
	 * @param parent
	 *            The PApplet object.
	 * @return The version number.
	 */
	@SuppressWarnings("all")
	public static int getProcessingVersion(PApplet parent) {

		// for version 3 PApplet inherits Object. Earlier ones inherit from
		// Applet.
		if (Applet.class.isInstance(parent)) {

			// the renderer P3D / OPENGL is the same for version 2
			if (parent.P3D == parent.OPENGL) {
				return 2;
			} else {
				return 1;
			}
		} else {
			return 3;
		}
	}
}
