// Path: api/src/main/java/de/ase34/flyingblocksapi/natives/api/NativeFlyingBlockHandler.java
// public abstract class NativeFlyingBlockHandler {
// 
//     protected FlyingBlock flyingBlock;
// 
//     public NativeFlyingBlockHandler(FlyingBlock flyingBlock) {
//         this.flyingBlock = flyingBlock;
//     }
// 
//     public abstract void spawnFlyingBlock(Location location);
// 
//     public abstract void removeEntites();
// 
//     public abstract void setFlyingBlockLocation(Location location);
// 
//     public abstract WitherSkull getBukkitEntity();
// 
// }
// 
// Path: api/src/main/java/de/ase34/flyingblocksapi/natives/api/NativesAPI.java
// public abstract class NativesAPI {
// 
//     protected static NativesAPI singleton;
// 
//     public static NativesAPI getSingleton() {
//         return singleton;
//     }
// 
//     public static void setSingleton(NativesAPI singleton) {
//         NativesAPI.singleton = singleton;
//     }
// 
//     public abstract List<Entity> removeFlyingBlocks(World world);
// 
//     public abstract void initialize();
// 
//     public abstract NativeFlyingBlockHandler createFlyingBlockHandler(FlyingBlock flyingBlock);
// 
// }


import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.WitherSkull;
import org.bukkit.util.Vector;
import de.ase34.flyingblocksapi.natives.api.NativeFlyingBlockHandler;
import de.ase34.flyingblocksapi.natives.api.NativesAPI;
/**
 * flyingblocksapi Copyright (C) 2014 ase34 and contributors
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
package de.ase34.flyingblocksapi;



/**
 * Handles the entities required for making a flying block.
 */
public abstract class FlyingBlock {

    /**
     * Default age for the horse.
     */
    public static int AGE = -4077000;
    /**
     * Default height offset for the skull.
     */
    public static double OFFSET = 100;
    /**
     * Default tracker update interval in ticks.
     */
    public static int UPDATE_INTERVAL = 2;

    protected final Material material;
    protected final byte materialData;
    protected final int trackerUpdateInterval;
    protected final double heightOffset;
    protected final int horseAge;

    protected NativeFlyingBlockHandler nativeHander;

    /**
     * Convenience constructor, uses {@link FlyingBlock#FlyingBlock(Material, byte, int, double, int)}
     * with {@link FlyingBlock#AGE} as age parameter, {@link FlyingBlock#OFFSET} as offset parameter and
     * {@link FlyingBlock#UPDATE_INTERVAL} as update interval parameter.
     * 
     * @param material
     *            The material
     * @param materialData
     *            The material's data
     */
    public FlyingBlock(Material material, byte materialData) {
        this(material, materialData, UPDATE_INTERVAL, OFFSET, AGE);
    }

    /**
     * Convenience constructor, uses {@link FlyingBlock#FlyingBlock(Material, byte, int, double, int)}
     * with {@link FlyingBlock#AGE} as age parameter and {@link FlyingBlock#OFFSET} as offset parameter.
     * 
     * @param material
     *            The material
     * @param materialData
     *            The material's data
     * @param trackerUpdateInterval
     *            The update interval of the tracker (in ticks)
     */
    public FlyingBlock(Material material, byte materialData, int trackerUpdateInterval) {
        this(material, materialData, trackerUpdateInterval, OFFSET, AGE);
    }

    /**
     * Constructs a new {@link FlyingBlock}.
     * 
     * @param material
     *            The material
     * @param materialData
     *            The material's data
     * @param trackerUpdateInterval
     *            The update interval of the tracker (in ticks)
     * @param heightOffset
     *            The height offset of the skull
     * @param horseAge
     *            The age of the horse
     * 
     * @throws IllegalStateException
     *             Thrown if the singleton of {@link NativesAPI} was not set yet.
     */
    public FlyingBlock(Material material, byte materialData, int trackerUpdateInterval,
            double heightOffset, int horseAge) {
        this.material = material;
        this.materialData = materialData;
        this.trackerUpdateInterval = trackerUpdateInterval;
        this.heightOffset = heightOffset;
        this.horseAge = horseAge;

// Path: api/src/main/java/de/ase34/flyingblocksapi/natives/api/NativeFlyingBlockHandler.java
// public abstract class NativeFlyingBlockHandler {
// 
//     protected FlyingBlock flyingBlock;
// 
//     public NativeFlyingBlockHandler(FlyingBlock flyingBlock) {
//         this.flyingBlock = flyingBlock;
//     }
// 
//     public abstract void spawnFlyingBlock(Location location);
// 
//     public abstract void removeEntites();
// 
//     public abstract void setFlyingBlockLocation(Location location);
// 
//     public abstract WitherSkull getBukkitEntity();
// 
// }
// 
// Path: api/src/main/java/de/ase34/flyingblocksapi/natives/api/NativesAPI.java
// public abstract class NativesAPI {
// 
//     protected static NativesAPI singleton;
// 
//     public static NativesAPI getSingleton() {
//         return singleton;
//     }
// 
//     public static void setSingleton(NativesAPI singleton) {
//         NativesAPI.singleton = singleton;
//     }
// 
//     public abstract List<Entity> removeFlyingBlocks(World world);
// 
//     public abstract void initialize();
// 
//     public abstract NativeFlyingBlockHandler createFlyingBlockHandler(FlyingBlock flyingBlock);
// 
// }


// Path: api/src/main/java/de/ase34/flyingblocksapi/FlyingBlock.java
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.WitherSkull;
import org.bukkit.util.Vector;
import de.ase34.flyingblocksapi.natives.api.NativeFlyingBlockHandler;
import de.ase34.flyingblocksapi.natives.api.NativesAPI;

/**
 * flyingblocksapi Copyright (C) 2014 ase34 and contributors
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
package de.ase34.flyingblocksapi;



/**
 * Handles the entities required for making a flying block.
 */
public abstract class FlyingBlock {

    /**
     * Default age for the horse.
     */
    public static int AGE = -4077000;
    /**
     * Default height offset for the skull.
     */
    public static double OFFSET = 100;
    /**
     * Default tracker update interval in ticks.
     */
    public static int UPDATE_INTERVAL = 2;

    protected final Material material;
    protected final byte materialData;
    protected final int trackerUpdateInterval;
    protected final double heightOffset;
    protected final int horseAge;

    protected NativeFlyingBlockHandler nativeHander;

    /**
     * Convenience constructor, uses {@link FlyingBlock#FlyingBlock(Material, byte, int, double, int)}
     * with {@link FlyingBlock#AGE} as age parameter, {@link FlyingBlock#OFFSET} as offset parameter and
     * {@link FlyingBlock#UPDATE_INTERVAL} as update interval parameter.
     * 
     * @param material
     *            The material
     * @param materialData
     *            The material's data
     */
    public FlyingBlock(Material material, byte materialData) {
        this(material, materialData, UPDATE_INTERVAL, OFFSET, AGE);
    }

    /**
     * Convenience constructor, uses {@link FlyingBlock#FlyingBlock(Material, byte, int, double, int)}
     * with {@link FlyingBlock#AGE} as age parameter and {@link FlyingBlock#OFFSET} as offset parameter.
     * 
     * @param material
     *            The material
     * @param materialData
     *            The material's data
     * @param trackerUpdateInterval
     *            The update interval of the tracker (in ticks)
     */
    public FlyingBlock(Material material, byte materialData, int trackerUpdateInterval) {
        this(material, materialData, trackerUpdateInterval, OFFSET, AGE);
    }

    /**
     * Constructs a new {@link FlyingBlock}.
     * 
     * @param material
     *            The material
     * @param materialData
     *            The material's data
     * @param trackerUpdateInterval
     *            The update interval of the tracker (in ticks)
     * @param heightOffset
     *            The height offset of the skull
     * @param horseAge
     *            The age of the horse
     * 
     * @throws IllegalStateException
     *             Thrown if the singleton of {@link NativesAPI} was not set yet.
     */
    public FlyingBlock(Material material, byte materialData, int trackerUpdateInterval,
            double heightOffset, int horseAge) {
        this.material = material;
        this.materialData = materialData;
        this.trackerUpdateInterval = trackerUpdateInterval;
        this.heightOffset = heightOffset;
        this.horseAge = horseAge;

        if (NativesAPI.getSingleton() == null) {