local profile = require("core.profile")
local timers = require("level.timer")
local kVariableDuration = -1
local tbl_DefaultShakes = {
  GateMovement = {
    name = "FSE_SHAKE_VERTICAL_SLIDING",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3
  },
  GateMovement_Light = {
    name = "FSE_SHAKE_SPARKS",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3
  },
  Roar = {
    name = "FSE_SHAKE_ROAR",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3
  },
  ElevatorMovement = {
    name = "FSE_SWAY_BOUYANT_ZIPLINE_NORMAL",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_GENERIC_RUMBLE_MEDIUM"
  },
  ElevatorMovement_Light = {
    name = "FSE_SHAKE_VERTICAL_SLIDING",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_GENERIC_RUMBLE_LOW"
  },
  ElevatorMovementFU_Light = {
    name = "FSE_SHAKE_VERTICAL_SLIDING",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3,
    followup = "ElevatorMovement_Reached"
  },
  ElevatorMovement_Reached = {
    name = "FSE_SHAKE_SWITCH_CLUNK_LIGHT",
    duration = 1.4,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_SMALLER"
  },
  GateLeveled = {
    name = "FSE_SHAKE_SWITCH_CLUNK_VERYLIGHT",
    duration = 0.6,
    tweenin = 0.3,
    tweenOut = 0
  },
  WaterMovement = {
    name = "FSE_SWAY_WATER_ROLLING",
    duration = kVariableDuration,
    tweenin = 0.3,
    tweenOut = 0,
    rumble = "FFB_GROUNDSHAKE_4S"
  },
  ShakeRumbleSmall = {
    name = "FSE_SHAKE_GENERIC_SMALL",
    duration = 1.15,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_SMALL"
  },
  ShakeRumbleMedium = {
    name = "FSE_SHAKE_GENERIC_MEDIUM",
    duration = 1.15,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_MEDIUM"
  },
  ShakeRumbleLarge = {
    name = "FSE_SHAKE_GENERIC_LARGE",
    duration = 1.15,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_LARGE"
  },
  ShakeRumbleGiant = {
    name = "FSE_SHAKE_GENERIC_GIANT",
    duration = 1.15,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_GIANT"
  },
  ShakeRumbleTitan = {
    name = "FSE_SHAKE_GENERIC_TITAN",
    duration = 1.15,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_SLAM"
  },
  FireTurretRiseAndStop = {
    name = "FSE_SHAKE_SLIDING_OBJECT_HEAVY",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_GENERIC_RUMBLE_LOW",
    followup = "ElevatorMovement_Reached"
  },
  CrumbleLower = {
    name = "FSE_SHAKE_TREMORS_LEVEL_0",
    duration = kVariableDuration,
    tweenin = 0.1,
    tweenOut = 0.5,
    rumble = "FFB_GENERIC_RUMBLE_LOW"
  },
  CrumbleLow = {
    name = "FSE_SHAKE_TREMORS_LEVEL_1",
    duration = kVariableDuration,
    tweenin = 0.6,
    tweenOut = 0.5,
    rumble = "FFB_GENERIC_RUMBLE_LOW"
  },
  CrumbleMedium = {
    name = "FSE_SHAKE_TREMORS_LEVEL_2",
    duration = kVariableDuration,
    tweenin = 0.3,
    tweenOut = 0.5,
    rumble = "FFB_GENERIC_RUMBLE_MEDIUM"
  },
  CrumbleGeneric = {
    name = "FSE_SHAKE_GROUND_IMPACT",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.5,
    rumble = "FFB_GENERIC_RUMBLE_MEDIUM"
  },
  ImpactMedium = {
    name = "FSE_SHAKE_SLAM_MEDIUM",
    duration = kVariableDuration,
    tweenin = 0.2,
    tweenOut = 0.8,
    rumble = "FFB_GENERIC_RUMBLE_MEDIUM"
  },
  EnemyLanding = {
    name = "FSE_SHAKE_VERTICAL_LANDING",
    duration = 0.5,
    tweenin = 0,
    tweenOut = 0,
    rumble = "FFB_MEDIUM"
  },
  HorizontalSliding = {
    name = "FSE_SHAKE_SLIDING_HORIZONTAL_LIGHT",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_GENERIC_RUMBLE_LOW"
  },
  VerticalSliding = {
    name = "FSE_SHAKE_VERTICAL_SLIDING",
    duration = kVariableDuration,
    tweenin = 0,
    tweenOut = 0.3,
    rumble = "FFB_GENERIC_RUMBLE_LOW"
  }
}
local IsValidShakeType = function(typeOfShake)
  assert(typeOfShake, "IsValidShakeType(): PlayGenericShake() was called with no type")
  if tbl_DefaultShakes[typeOfShake] then
    return true
  end
  return false
end
local PlayShakeOG = function(nameOfEffect, duration, tweenIn, tweenOut)
  local ti = tweenIn or 0
  local to = tweenOut or 0
  local effect = {
    EffectName = nameOfEffect,
    Duration = duration,
    TweenInTime = ti,
    TweenOutTime = to
  }
  game.FX.SubmitEffect(effect)
end
local PlayShake = function(nameOfEffect, duration, tweenIn, tweenOut)
  local ti = tweenIn or 0
  local to = tweenOut or 0
  local effect = {
    Name = nameOfEffect,
    Duration = duration,
    TweenIn = {Time = ti},
    TweenOut = {Time = to}
  }
  game.Blender.Trigger(effect)
end
local PlayEffectTable = function(tEffect)
  game.Blender.Trigger(tEffect)
end
local PlayEffect = function(nameOfEffect, duration, tweenIn, tweenOut)
  local ti = tweenIn or 0
  local to = tweenOut or 0
  local effect = {
    Name = nameOfEffect,
    Duration = duration,
    TweenIn = {Time = ti},
    TweenOut = {Time = to}
  }
  game.Blender.Trigger(effect)
end
local function PlayDefaultShake(typeOfShake, duration, tweenIn, tweenOut)
  assert(IsValidShakeType(typeOfShake), "PlayDefaultShake() Error: This typeOfShake: " .. typeOfShake .. " does not exist")
  local name = tbl_DefaultShakes[typeOfShake].name
  local d = duration or tbl_DefaultShakes[typeOfShake].duration
  local ti = tweenIn or tbl_DefaultShakes[typeOfShake].tweenin
  local to = tweenOut or tbl_DefaultShakes[typeOfShake].tweenout
  local rumble = tbl_DefaultShakes[typeOfShake].rumble
  assert(0 < d, "PlayGenericShake(" .. typeOfShake .. ") needs a duration specified")
  PlayEffect(name, d, ti, to)
  if rumble ~= nil then
    PlayEffect(rumble, d, ti, to)
  end
  local followupshaketype = tbl_DefaultShakes[typeOfShake].followup
  if followupshaketype ~= nil then
    local delay = duration
    timers.StartLevelTimer(delay, function()
      PlayDefaultShake(followupshaketype)
    end)
  end
end
return profile.WrapLibrary({
  PlayShake = PlayShake,
  PlayShakeOG = PlayShakeOG,
  PlayEffect = PlayEffect,
  PlayEffectTable = PlayEffectTable,
  PlayDefaultShake = PlayDefaultShake
})
