package de.craften.plugins.rpgplus.scripting.api;

import org.bukkit.plugin.Plugin;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;

/**
 * Lua API for using the scheduler.
 */
public class Scheduler extends LuaTable {
    public Scheduler(final Plugin plugin) {
        set("async", new OneArgFunction() {
            @Override
            public LuaValue call(final LuaValue function) {
                return new ZeroArgFunction() {
                    @Override
                    public LuaValue call() {
                        plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
                            @Override
                            public void run() {
                                function.checkfunction().invoke();
                            }
                        });
                        return LuaValue.NIL;
                    }
                };
            }
        });

        set("sync", new OneArgFunction() {
            @Override
            public LuaValue call(final LuaValue function) {
                return new ZeroArgFunction() {
                    @Override
                    public LuaValue call() {
                        plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
                            @Override
                            public void run() {
                                function.checkfunction().invoke();
                            }
                        });
                        return LuaValue.NIL;
                    }
                };
            }
        });

        set("delay", new TwoArgFunction() {
            @Override
            public LuaValue call(final LuaValue delay, final LuaValue function) {
                return new ZeroArgFunction() {
                    @Override
                    public LuaValue call() {
                        plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
                            @Override
                            public void run() {
                                function.checkfunction().invoke();
                            }
                        }, delay.checklong());
                        return LuaValue.NIL;
                    }
                };
            }
        });

        set("repeat", new VarArgFunction() {
            @Override
            public LuaValue invoke(final Varargs varargs) {
                return new ZeroArgFunction() {
                    @Override
                    public LuaValue call() {
                        if (varargs.narg() == 2) {
                            return LuaValue.valueOf(plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
                                @Override
                                public void run() {
                                    varargs.checkfunction(2).invoke();
                                }
                            }, 0, varargs.checklong(1)));
                        } else if (varargs.narg() == 3) {
                            return LuaValue.valueOf(plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
                                @Override
                                public void run() {
                                    varargs.checkfunction(3).invoke();
                                }
                            }, varargs.checklong(1), varargs.checklong(2)));
                        } else {
                            throw new LuaError("Invalid number of arguments, expected 2 or 3.");
                        }
                    }
                };
            }
        });

        set("cancel", new OneArgFunction() {
            @Override
            public LuaValue call(LuaValue luaValue) {
                plugin.getServer().getScheduler().cancelTask(luaValue.checkint());
                return LuaValue.NIL;
            }
        });
    }
}

@@ -319,49 +319,8 @@
 ion;
-%0Aimport org.luaj.vm2.lib.ZeroArgFunction;
 %0A%0A/*
@@ -592,36 +592,35 @@
      return new 
-Zero
+Var
 ArgFunction() %7B%0A
@@ -677,37 +677,60 @@
 public LuaValue 
-call(
+invoke(final Varargs varargs
 ) %7B%0A            
@@ -964,32 +964,39 @@
 nction().invoke(
+varargs
 );%0A             
@@ -1297,36 +1297,35 @@
      return new 
-Zero
+Var
 ArgFunction() %7B%0A
@@ -1382,37 +1382,60 @@
 public LuaValue 
-call(
+invoke(final Varargs varargs
 ) %7B%0A            
@@ -1671,32 +1671,39 @@
 nction().invoke(
+varargs
 );%0A             
@@ -2027,36 +2027,35 @@
      return new 
-Zero
+Var
 ArgFunction() %7B%0A
@@ -2112,37 +2112,60 @@
 public LuaValue 
-call(
+invoke(final Varargs varargs
 ) %7B%0A            
@@ -2168,32 +2168,56 @@
                 
+return LuaValue.valueOf(
 plugin.getServer
@@ -2425,32 +2425,39 @@
 nction().invoke(
+varargs
 );%0A             
@@ -2522,53 +2522,9 @@
 g())
-;%0A                        return LuaValue.NIL
+)
 ;%0A  
@@ -2747,12 +2747,11 @@
 new 
-Zero
+Var
 ArgF
@@ -2828,21 +2828,44 @@
 uaValue 
-call(
+invoke(final Varargs varargs
 ) %7B%0A    
@@ -3202,32 +3202,39 @@
 ction(2).invoke(
+varargs
 );%0A             
@@ -3669,16 +3669,23 @@
 .invoke(
+varargs
 );%0A     

Return the task id in the delay function. Put original arguments into callback function in all scheduler functions.