block load
{
  es_xdoblock corelib/repeat/repeat_register
}

block repeat_register
{
  // variables used by repeat
  es_xsetinfo _repeat_commandcount 0
  es_xsetinfo _repeat_action 0
  es_xsetinfo _repeat_name 0
  es_xsetinfo _repeat_paused 0
  es_xsetinfo _repeat_interval 0
  es_xsetinfo _repeat_ccount 0
  es_xsetinfo _repeat_count 0
  es_xsetinfo _repeat_started 0
  es_xsetinfo _repeat_output 0
  es_xsetinfo _repeat_command 0
  es_xsetinfo _repeat_limit 0
  es_xsetinfo _repeat_argcommandcount 0
  es_xsetinfo _repeat_initialized 0
  // check to see if repeat exists
  es_xexists _exists command repeat
  if (server_var(_exists) = 0) do
  {
    es_xregcmd repeat corelib/repeat/repeat "Creates a pausable loop, with a set interval and command execution limit"
  }
  es_xexists _exists command _do_check_repeat
  if (server_var(_exists) = 0) do
  {
    es_xregcmd _do_check_repeat corelib/repeat/check_repeat "Internal command used by the script and only the script"
  }
  es_xexists _exists keygroup repeat
  if (server_var(_exists) = 0) do
  {
    es_xkeygroupcreate repeat
  }
}

// Originally submitted by SumGuy14 with code by Chun
block repeat
{
  es_xgetargv _repeat_action 1
  es es_xif (server_var(_repeat_action) = create) do
  {
    es_xdoblock corelib/repeat/repeat_action_create_check
  }
  else do
  {
    es es_xif (server_var(_repeat_action) = start) do
    {
      es_xdoblock corelib/repeat/repeat_action_start_check
    }
    else do
    {
      es es_xif (server_var(_repeat_action) = pause) do
      {
        es_xdoblock corelib/repeat/repeat_action_pause_check
      }
      else do
      {
        es es_xif (server_var(_repeat_action) = resume) do
        {
          es_xdoblock corelib/repeat/repeat_action_resume_check
        }
        else do
        {
          es es_xif (server_var(_repeat_action) = stop) do
          {
            es_xdoblock corelib/repeat/repeat_action_stop_check
          }
          else do
          {
            es es_xif (server_var(_repeat_action) = delete) do
            {
              es_xdoblock corelib/repeat/repeat_action_delete_check
            }
            else do
            {
              es es_xif (server_var(_repeat_action) = status) do
              {
                es_xdoblock corelib/repeat/repeat_action_status
              }
              else do
              {
                es_xdbgmsg 0 repeat: Invalid subcommand for repeat
              }
            }
          }
        }
      }
    }
  }
}

block repeat_action_create_check
{
  es_xgetargv _repeat_name 2
  es es_xif (server_var(_repeat_name) != 0) do
  {
    es es_xexists _tempcore key repeat server_var(_repeat_name)
    es es_xif (server_var(_tempcore) = 0) do
    {
      es_xdoblock corelib/repeat/repeat_action_create
    }
    else do
    {
      es es_xdbgmsg 0 repeat: The repeat command already exists: server_var(_repeat_name)
    }
  }
  else do
  {
    es_xdbgmsg 0 repeat: Invalid arguments to repeat create. Syntax: repeat create <name> <command>
  }
}

block repeat_action_start_check
{
  es_xgetargv _repeat_name 2
  es es_xif (server_var(_repeat_name) != 0) do
  {
    es es_xexists _tempcore key repeat server_var(_repeat_name)
    es es_xif (server_var(_tempcore) = 1) do
    {
      es_xdoblock corelib/repeat/repeat_action_start
    }
    else do
    {
      es es_xdbgmsg 0 repeat: The repeat command does not exist: server_var(_repeat_name)
    }
  }
  else do
  {
    es_xdbgmsg 0 repeat: Invalid arguments to repeat start. Syntax: repeat start <name> <interval> [number-of-times]
  }
}

block repeat_action_pause_check
{
  es_xgetargv _repeat_name 2
  es es_xif (server_var(_repeat_name) != 0) do
  {
    es es_xexists _tempcore key repeat server_var(_repeat_name)
    es es_xif (server_var(_tempcore) = 1) do
    {
      es es_xkeygetvalue _repeat_paused repeat server_var(_repeat_name) paused
      es es_xif (server_var(_repeat_paused) = 0) do
      {
        es es_xkeysetvalue repeat server_var(_repeat_name) paused 1
      }
      else do
      {
        es es_xdbgmsg 0 repeat: Already paused: server_var(_repeat_name)
      }
    }
    else do
    {
      es es_xdbgmsg 0 repeat: The repeat command does not exist: server_var(_repeat_name)
    }
  }
  else do
  {
    es_xdbgmsg 0 repeat: Invalid arguments to repeat pause. Syntax: repeat pause <name>
  }
}

block repeat_action_resume_check
{
  es_xgetargv _repeat_name 2
  es es_xif (server_var(_repeat_name) != 0) do
  {
    es es_xexists _tempcore key repeat server_var(_repeat_name)
    es es_xif (server_var(_tempcore) = 1) do
    {
      es es_xkeygetvalue _repeat_interval repeat server_var(_repeat_name) interval
      es es_xif (server_var(_repeat_interval) > 0) do
      {
        es es_xkeygetvalue _repeat_paused repeat server_var(_repeat_name) paused
        es es_xif (server_var(_repeat_paused) = 1) do
        {
          es es_xkeysetvalue repeat server_var(_repeat_name) paused 0
          es es_xstring _repeat_commandcount replace _repeat_
          es_xmath _repeat_commandcount + 1
          es es_xformat _repeat_commandcount "_repeat_%1" server_var(_repeat_commandcount)
          es es_xsetinfo server_var(_repeat_commandcount) server_var(_repeat_name)
          es es_xkeysetvalue repeat server_var(_repeat_name) ccount server_var(_repeat_commandcount)
          es_xdoblock corelib/repeat/repeat_loop
        }
        else do
        {
          es es_xdbgmsg 0 repeat: Already running: server_var(_repeat_name)
        }
      }
      else do
      {
        es es_xdbgmsg 0 repeat: You can't resume a stopped command.  Use repeat start: server_var(_repeat_name)
      }
    }
    else do
    {
      es es_xdbgmsg 0 repeat: The repeat command does not exist: server_var(_repeat_name)
    }
  }
  else do
  {
    es_xdbgmsg 0 repeat: Invalid arguments to repeat resume. Syntax: repeat resume <name>
  }
}

block repeat_action_stop_check
{
  es_xgetargv _repeat_name 2
  es es_xif (server_var(_repeat_name) != 0) do
  {
    es es_xexists _tempcore key repeat server_var(_repeat_name)
    es es_xif (server_var(_tempcore) = 1) do
    {
      es es_xkeygetvalue _repeat_paused repeat server_var(_repeat_name) started
      es es_xif (server_var(_repeat_paused) = 1) do
      {
        es es_xkeygetvalue _repeat_ccount repeat server_var(_repeat_name) ccount
        es alias server_var(_repeat_ccount) ""
        es es_xkeysetvalue repeat server_var(_repeat_name) interval 0
        es es_xkeysetvalue repeat server_var(_repeat_name) limit 0
        es es_xkeysetvalue repeat server_var(_repeat_name) count 0
        es es_xkeysetvalue repeat server_var(_repeat_name) paused 0
        es es_xkeysetvalue repeat server_var(_repeat_name) started 0
        es es_xkeysetvalue repeat server_var(_repeat_name) initialized 0
      }
      else do
      {
        es es_xdbgmsg 0 repeat: Already stopped: server_var(_repeat_name)
      }
    }
    else do
    {
      es es_xdbgmsg 0 repeat: The repeat command does not exist: server_var(_repeat_name)
    }
  }
  else do
  {
    es_xdbgmsg 0 repeat: Invalid arguments to repeat stop. Syntax: repeat stop <name>
  }
}

block repeat_action_delete_check
{
  es_xgetargv _repeat_name 2
  es es_xif (server_var(_repeat_name) != 0) do
  {
    es es_xexists _tempcore key repeat server_var(_repeat_name)
    es es_xif (server_var(_tempcore) = 1) do
    {
      es es_xkeygetvalue _repeat_started repeat server_var(_repeat_name) started
      es es_xif (server_var(_repeat_started) = 1) do
      {
        es repeat stop server_var(_repeat_name)
      }
      es es_xkeydelete repeat server_var(_repeat_name)
    }
    else do
    {
      es es_xdbgmsg 0 repeat: Repeat command does not exist: server_var(_repeat_name)
    }
  }
  else do
  {
    es_xdbgmsg 0 repeat: Invalid arguments to repeat delete. Syntax: repeat delete <name>
  }
}

block repeat_action_status
{
  es_xgetargc _repeat_count
  es es_xif (server_var(_repeat_count) => 4) do
  {
    es_xgetargv _repeat_output 2
    es_xgetargv _repeat_name 3
    es es_xexists _tempcore key repeat server_var(_repeat_name)
    es es_xif (server_var(_tempcore) = 1) do
    {
      es es_xkeygetvalue _repeat_started repeat server_var(_repeat_name) started
      es es_xkeygetvalue _repeat_paused repeat server_var(_repeat_name) paused
      es es_xif (server_var(_repeat_started) = 0) do
      {
        es es_xsetinfo server_var(_repeat_output) 1
      }
      else do
      {
        es es_xif (server_var(_repeat_paused) = 0) do
        {
          es es_xsetinfo server_var(_repeat_output) 2
        }
        else do
        {
          es es_xsetinfo server_var(_repeat_output) 3
        }
      }
    }
    else do
    {
      es es_xsetinfo server_var(_repeat_output) 0
    }
  }
  else do
  {
    es_xdbgmsg 0 repeat: Not enough arguments to repeat status. Syntax: repeat status <var> <name>
  }
}

block repeat_action_create
{
  es_xgetargv _repeat_command 3
  es es_xif (server_var(_repeat_command) != 0) do
  {
    es es_xkeycreate repeat server_var(_repeat_name)
    es es_xkeysetvalue repeat server_var(_repeat_name) command server_var(_repeat_command)
    es es_xkeysetvalue repeat server_var(_repeat_name) interval 0
    es es_xkeysetvalue repeat server_var(_repeat_name) limit 0
    es es_xkeysetvalue repeat server_var(_repeat_name) count 0
    es es_xkeysetvalue repeat server_var(_repeat_name) paused 0
    es es_xkeysetvalue repeat server_var(_repeat_name) started 0
    es es_xkeysetvalue repeat server_var(_repeat_name) initialized 0
    es es_xkeysetvalue repeat server_var(_repeat_name) ccount 0
  }
  else do
  {
    es_xdbgmsg 0 repeat: Invalid arguments to repeat create. Syntax: repeat create <name> <command>
  }
}

block repeat_action_start
{
  es_xgetargv _repeat_interval 3
  es_xgetargv _repeat_limit 4
  es es_xif (server_var(_repeat_interval) > 0) do
  {
    es es_xkeygetvalue _repeat_started repeat server_var(_repeat_name) started
    es es_xif (server_var(_repeat_started) = 0) do
    {
      es_xstring _repeat_commandcount replace _repeat_
      es_xmath _repeat_commandcount + 1
      es es_xformat _repeat_commandcount "_repeat_%1" server_var(_repeat_commandcount)
      es es_xsetinfo server_var(_repeat_commandcount) server_var(_repeat_name)
      es es_xkeysetvalue repeat server_var(_repeat_name) interval server_var(_repeat_interval)
      es es_xkeysetvalue repeat server_var(_repeat_name) limit server_var(_repeat_limit)
      es es_xkeysetvalue repeat server_var(_repeat_name) count 0
      es es_xkeysetvalue repeat server_var(_repeat_name) paused 0
      es es_xkeysetvalue repeat server_var(_repeat_name) started 1
      es es_xkeysetvalue repeat server_var(_repeat_name) initialized 0
      es es_xkeysetvalue repeat server_var(_repeat_name) ccount server_var(_repeat_commandcount)
      es_xdoblock corelib/repeat/repeat_loop
    }
    else do
    {
      es es_xdbgmsg 0 repeat: Already started: server_var(_repeat_name)
    }
  }
  else do
  {
    es_xdbgmsg 0 repeat: Invalid arguments to repeat start. Syntax: repeat start <name> <interval> [number-of-times]
  }
}

block repeat_loop
{
  es _do_check_repeat server_var(_repeat_commandcount)
}

block check_repeat
{
  es_xgetargv _repeat_argcommandcount 1
  es es_xexists _tempcore key repeat server_var(server_var(_repeat_argcommandcount))
  es es_xif (server_var(_tempcore) = 1) do
  {
    es es_xkeygetvalue _repeat_interval repeat server_var(server_var(_repeat_argcommandcount)) interval
    es es_xkeygetvalue _repeat_initialized repeat server_var(server_var(_repeat_argcommandcount)) initialized
    es es_xif (server_var(_repeat_initialized) = 1) do
    {
      es es_xkeygetvalue _repeat_paused repeat server_var(server_var(_repeat_argcommandcount)) paused
      es es_xif (server_var(_repeat_paused) = 0) do
      {
        es es_xkeygetvalue _repeat_paused repeat server_var(server_var(_repeat_argcommandcount)) started
        es es_xif (server_var(_repeat_paused) = 1) do
        {
          es es_xkeygetvalue _repeat_command repeat server_var(server_var(_repeat_argcommandcount)) command
          es es_xkeygetvalue _repeat_limit repeat server_var(server_var(_repeat_argcommandcount)) limit
          es es_xkeygetvalue _repeat_count repeat server_var(server_var(_repeat_argcommandcount)) count
          es es_xif (server_var(_repeat_limit) = 0) do
          {
            es alias _repeat_command_alias server_var(_repeat_command)
            _repeat_command_alias
            es_xsetinfo _repeat_do_repeat "_do_check_repeat server_var(_repeat_argcommandcount)"
            es es_xnq es es_xnq _repeat_do_repeat server_var(_repeat_do_repeat)
            es alias server_var(_repeat_argcommandcount) server_var(_repeat_do_repeat)
            es es_xdelayed server_var(_repeat_interval) server_var(_repeat_argcommandcount)
          }
          else do
          {
            es_xmath _repeat_count + 1
            es es_xkeysetvalue repeat server_var(server_var(_repeat_argcommandcount)) count server_var(_repeat_count)
            es alias _repeat_command_alias server_var(_repeat_command)
            _repeat_command_alias
            es es_xif (server_var(_repeat_count) < server_var(_repeat_limit)) do
            {
              es_xsetinfo _repeat_do_repeat "_do_check_repeat server_var(_repeat_argcommandcount)"
              es es_xnq es es_xnq _repeat_do_repeat server_var(_repeat_do_repeat)
              es alias server_var(_repeat_argcommandcount) server_var(_repeat_do_repeat)
              es es_xdelayed server_var(_repeat_interval) server_var(_repeat_argcommandcount)
            }
            else do
            {
              es es_xkeysetvalue repeat server_var(server_var(_repeat_argcommandcount)) interval 0
              es es_xkeysetvalue repeat server_var(server_var(_repeat_argcommandcount)) limit 0
              es es_xkeysetvalue repeat server_var(server_var(_repeat_argcommandcount)) count 0
              es es_xkeysetvalue repeat server_var(server_var(_repeat_argcommandcount)) paused 0
              es es_xkeysetvalue repeat server_var(server_var(_repeat_argcommandcount)) started 0
            }
          }
        }
      }
    }
    else do
    {
      es es_xkeysetvalue repeat server_var(server_var(_repeat_argcommandcount)) count 0
      es es_xkeysetvalue repeat server_var(server_var(_repeat_argcommandcount)) initialized 1
      es_xsetinfo _repeat_do_repeat "_do_check_repeat server_var(_repeat_argcommandcount)"
      es es_xnq es es_xnq _repeat_do_repeat server_var(_repeat_do_repeat)
      es alias server_var(_repeat_argcommandcount) server_var(_repeat_do_repeat)
      es es_xdelayed server_var(_repeat_interval) server_var(_repeat_argcommandcount)
    }
  }
}

// Repeat tests

block repeat_starttests
{
  es_delayed 1 es_xdoblock corelib/repeat/repeat_test1
  echo
  echo
  echo Testing repeat functionality
  echo
  echo
}

block repeat_test1
{
  repeat delete test
  repeat create test "echo I shall be repeated every second 5 times!"
  repeat start test 1 5
  es_xdelayed 6 echo Done!
  es_xdelayed 6 echo
  es_xdelayed 6 echo Testing sub-functions (pause resume)
  es_xdelayed 6 echo
  es_xdelayed 6 echo
  es_xdelayed 7 repeat delete test
  es_xdelayed 7 repeat create test "echo I shall be repeated every second 10 times!"
  es_xdelayed 7 repeat start test 1 10
  es_xdelayed 10 repeat pause test
  es_xdelayed 10 echo Paused for 3 seconds
  es_xdelayed 13 echo Resumed
  es_xdelayed 13 repeat resume test
  es_xdelayed 22 echo Done!
  es_xdelayed 22 repeat delete test
  es_xdelayed 23 echo If you don't see any "Done!" messages and the message's are false, then something is definetly broken
  es_xdelayed 23 echo
  es_xdelayed 23 echo
  es_xdelayed 23 echo Finished test 1, starting next test
  es_xdelayed 23 es_xdoblock corelib/repeat/repeat_test2a
}

block repeat_test2a
{
  echo
  echo
  echo Testing functionality of doing blocks within repeat
  echo
  echo
  repeat delete test
  repeat create test "es_xdoblock corelib/repeat/repeat_test2b"
  repeat start test 2 5
  es_xdelayed 13 repeat delete test
  es_xdelayed 13 echo
  es_xdelayed 13 echo
  es_xdelayed 13 echo If the message is false then something is definetly broken
  es_xdelayed 13 echo Finished test 2, starting next test
  es_xdelayed 13 es_xdoblock corelib/repeat/repeat_test3
}

block repeat_test2b
{
  echo Block executed perfectly!  This should appear every 2 seconds 5 times!
}

block repeat_test3
{
  echo
  echo
  echo Testing multiple commands running at once
  echo
  echo
  repeat delete test
  repeat delete test2
  repeat create test "echo This message should appear 10 times"
  repeat create test2 "echo This message should appear 5 times"
  repeat start test 1 10
  repeat start test2 2 5
  es_xdelayed 12 echo
  es_xdelayed 12 echo
  es_xdelayed 12 echo If messages are false then something is definetly broken
  es_xdelayed 12 echo
  es_xdelayed 12 echo Finished test 3, starting next test
  es_xdelayed 12 es_xdoblock corelib/repeat/repeat_test4
}

block repeat_test4
{
  // This is to test to see if errors are working
  repeat delete test
  echo
  echo
  echo Count errors pertaining to "repeat"  from here down
  echo
  echo
  repeat create test
  repeat create
  repeat start test
  repeat start
  repeat start blahblah
  repeat pause blahblah
  repeat pause
  repeat resume
  repeat resume blahblah
  repeat stop
  repeat stop blahblah
  repeat delete
  repeat delete blahblah
  repeat create test "echo "
  repeat create test "echo "
  repeat start test 1 10
  repeat start test 1 10
  repeat pause test
  repeat pause test
  repeat resume test
  repeat resume test
  repeat stop test
  repeat stop test
  echo
  echo
  echo Should be 17 errors. If not then something is definetly broken
}
