text:
package com.nrg.kelly.stages.actors;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.Filter;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Timer;
import com.google.common.base.Optional;
import com.google.common.eventbus.Subscribe;
import com.nrg.kelly.Constants;
import com.nrg.kelly.config.CameraConfig;
import com.nrg.kelly.config.actors.AtlasConfig;
import com.nrg.kelly.config.actors.HitVectorConfig;
import com.nrg.kelly.config.actors.ImageOffsetConfig;
import com.nrg.kelly.config.actors.ImageScaleConfig;
import com.nrg.kelly.config.actors.PositionConfig;
import com.nrg.kelly.events.game.ArmourPickedUpEvent;
import com.nrg.kelly.events.game.BossDeadEvent;
import com.nrg.kelly.events.game.FireRunnerWeaponEvent;
import com.nrg.kelly.events.game.GameOverEvent;
import com.nrg.kelly.config.actors.RunnerConfig;
import com.nrg.kelly.events.game.GunPickedUpEvent;
import com.nrg.kelly.events.game.RunnerEndLevelEvent;
import com.nrg.kelly.events.game.RunnerHitEvent;
import com.nrg.kelly.events.physics.BeginContactEvent;
import com.nrg.kelly.events.Events;
import com.nrg.kelly.events.screen.OnDoubleTapGestureEvent;
import com.nrg.kelly.events.screen.SlideControlInvokedEvent;
import com.nrg.kelly.events.game.JumpControlInvokedEvent;
import com.nrg.kelly.physics.Box2dFactory;

import java.util.List;

public class RunnerActor extends GameActor {

    private Animation jumpAnimation;
    private Animation slideAnimation;
    private Animation dieAnimation;
    private AtlasConfig jumpAtlasConfig;
    private AtlasConfig slideAtlasConfig;
    private AtlasConfig dieAtlasConfig;
    private boolean deathScheduled = false;
    private RunnerConfig runnerConfig;
    private AtlasConfig armourJumpAtlasConfig;
    private AtlasConfig armourSlideAtlasConfig;
    private AtlasConfig armourRunAtlasConfig;
    private Animation armourJumpAnimation;
    private Animation armourSlideAnimation;
    private Animation armourRunAnimation;
    private AnimationState animationState = AnimationState.DEFAULT;
    private AtlasConfig runGunAtlasConfig;
    private AtlasConfig jumpGunAtlasConfig;
    private AtlasConfig armourRunGunAtlasConfig;
    private AtlasConfig slideGunAtlasConfig;
    private AtlasConfig armourSlideGunAtlasConfig;
    private AtlasConfig armourJumpGunAtlasConfig;
    private Animation runGunAnimation;
    private Animation jumpGunAnimation;
    private Animation slideGunAnimation;
    private Animation armourJumpGunAnimation;
    private Animation armourSlideGunAnimation;
    private Animation armourRunGunAnimation;
    private Optional<PositionConfig> endOfLevelPosition = Optional.absent();
    private boolean destroyOnNextCollision = false;
    private boolean collidedWithDeadBoss = false;

    public RunnerActor(RunnerConfig runnerConfig, CameraConfig cameraConfig) {
        super(runnerConfig, cameraConfig);
        this.runnerConfig = runnerConfig;
        Events.get().register(this);
        setWidth(runnerConfig.getWidth());
        setHeight(runnerConfig.getHeight());
        this.createTextures();
    }

    public void createTextures(){
        //TODO: this is repetitive and should be abstracted
        final List<AtlasConfig> atlasConfigList = runnerConfig.getAnimations();
        setDefaultAtlasConfig(this.getAtlasConfigByName(atlasConfigList, "default"));
        runGunAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "run-gun");

        jumpAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "jump");
        jumpGunAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "jump-gun");

        slideAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "slide");
        slideGunAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "slide-gun");

        dieAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "die");

        armourJumpAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "armour-jump");
        armourJumpGunAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "armour-jump-gun");

        armourSlideAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "armour-slide");
        armourSlideGunAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "armour-slide-gun");

        armourRunAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "armour-run");
        armourRunGunAtlasConfig = this.getAtlasConfigByName(atlasConfigList, "armour-run-gun");

        final String run = getDefaultAtlasConfig().getAtlas();
        final String runGun = runGunAtlasConfig.getAtlas();

        final String jump = jumpAtlasConfig.getAtlas();
        final String jumpGun = jumpGunAtlasConfig.getAtlas();

        final String slide = slideAtlasConfig.getAtlas();
        final String slideGun = slideGunAtlasConfig.getAtlas();

        final String die = dieAtlasConfig.getAtlas();

        final String armourRun = armourRunAtlasConfig.getAtlas();
        final String armourRunGun = armourRunGunAtlasConfig.getAtlas();

        final String armourJump = armourJumpAtlasConfig.getAtlas();
        final String armourJumpGun = armourJumpGunAtlasConfig.getAtlas();

        final String armourSlide = armourSlideAtlasConfig.getAtlas();
        final String armourSlideGun = armourSlideGunAtlasConfig.getAtlas();

        final TextureAtlas defaultAtlas = new TextureAtlas(Gdx.files.internal(run));
        final TextureAtlas runGunAtlas = new TextureAtlas(Gdx.files.internal(runGun));

        final TextureAtlas jumpAtlas = new TextureAtlas(Gdx.files.internal(jump));
        final TextureAtlas jumpGunAtlas = new TextureAtlas(Gdx.files.internal(jumpGun));

        final TextureAtlas slideAtlas = new TextureAtlas(Gdx.files.internal(slide));
        final TextureAtlas slideGunAtlas = new TextureAtlas(Gdx.files.internal(slideGun));

        final TextureAtlas dieAtlas = new TextureAtlas(Gdx.files.internal(die));

        final TextureAtlas armourJumpAtlas = new TextureAtlas(Gdx.files.internal(armourJump));
        final TextureAtlas armourJumpGunAtlas = new TextureAtlas(Gdx.files.internal(armourJumpGun));

        final TextureAtlas armourSlideAtlas = new TextureAtlas(Gdx.files.internal(armourSlide));
        final TextureAtlas armourSlideGunAtlas = new TextureAtlas(Gdx.files.internal(armourSlideGun));

        final TextureAtlas armourRunAtlas = new TextureAtlas(Gdx.files.internal(armourRun));
        final TextureAtlas armourRunGunAtlas = new TextureAtlas(Gdx.files.internal(armourRunGun));

        setDefaultAnimation(new Animation(runnerConfig.getFrameRate(), defaultAtlas.getRegions()));
        runGunAnimation = new Animation(runnerConfig.getFrameRate(), runGunAtlas.getRegions());

        jumpAnimation = new Animation(runnerConfig.getFrameRate(), jumpAtlas.getRegions());
        jumpGunAnimation = new Animation(runnerConfig.getFrameRate(), jumpGunAtlas.getRegions());

        slideAnimation = new Animation(runnerConfig.getFrameRate(), slideAtlas.getRegions());
        slideGunAnimation = new Animation(runnerConfig.getFrameRate(), slideGunAtlas.getRegions());

        dieAnimation = new Animation(runnerConfig.getFrameRate(), dieAtlas.getRegions());

        armourJumpAnimation = new Animation(runnerConfig.getFrameRate(), armourJumpAtlas.getRegions());
        armourJumpGunAnimation = new Animation(runnerConfig.getFrameRate(), armourJumpGunAtlas.getRegions());

        armourSlideAnimation = new Animation(runnerConfig.getFrameRate(), armourSlideAtlas.getRegions());
        armourSlideGunAnimation = new Animation(runnerConfig.getFrameRate(), armourSlideGunAtlas.getRegions());

        armourRunAnimation = new Animation(runnerConfig.getFrameRate(), armourRunAtlas.getRegions());
        armourRunGunAnimation = new Animation(runnerConfig.getFrameRate(), armourRunGunAtlas.getRegions());

    }

    @Override
    public void draw(Batch batch, float parentAlpha) {

        super.draw(batch, parentAlpha);
        stateTime += Gdx.graphics.getDeltaTime();
        final TextureRegion region;
        final ActorState state = this.getActorState();
        final AnimationState animationState = this.getAnimationState();
        final Animation animation;
        final AtlasConfig atlasConfig;
        switch(state){
            case UPGRADING_ARMOUR:
                drawUpgradingAnimation(batch, animationState);
                break;
            case UPGRADING_GUN:
                drawUpgradingAnimation(batch, animationState);
                break;
            case SLIDING:
                animation = getSlideAnimation(animationState);
                region = animation.getKeyFrame(stateTime, true);
                drawSlideAnimation(batch, region);
                break;
            case JUMPING:
                animation = getJumpAnimation(animationState);
                region = animation.getKeyFrame(stateTime, true);
                atlasConfig = getJumpAtlasConfig(animationState);
                drawAnimation(batch,
                        region,
                        Optional.of(atlasConfig.getImageOffset()),
                        Optional.of(atlasConfig.getImageScale()));
                break;
            case HIT:
                maintainPosition();
                region = dieAnimation.getKeyFrame(stateTime, true);
                drawAnimation(batch,
                        region,
                        Optional.of(dieAtlasConfig.getImageOffset()),
                        Optional.of(dieAtlasConfig.getImageScale()));

                break;
            case FALLING:
                region = dieAnimation.getKeyFrame(stateTime, true);
                drawAnimation(batch,
                        region,
                        Optional.of(dieAtlasConfig.getImageOffset()),
                        Optional.of(dieAtlasConfig.getImageScale()));
                if(this.getBody().getPosition().y < 0){
                    Events.get().post(new GameOverEvent(this));
                }
                break;
            case RUNNING:
                animation = getRunAnimation(animationState);
                region = animation.getKeyFrame(stateTime, true);
                atlasConfig = getRunAtlasConfig(animationState);
                drawAnimation(batch,
                        region,
                        Optional.of(atlasConfig.getImageOffset()),
                        Optional.of(atlasConfig.getImageScale()));
                break;
        }

    }

    public boolean canFireWeapon() {
        return getAnimationState().equals(AnimationState.ARMOUR_AND_GUN_EQUIPPED)||
                getAnimationState().equals(AnimationState.GUN_EQUIPPED);
    }

    private AtlasConfig getRunAtlasConfig(final AnimationState animationState) {
        switch(animationState){
            case ARMOUR_EQUIPPED:
                return armourRunAtlasConfig;
            case ARMOUR_AND_GUN_EQUIPPED:
                return armourRunGunAtlasConfig;
            case GUN_EQUIPPED:
                return runGunAtlasConfig;
            default:
                return getDefaultAtlasConfig();
        }
    }

    private Animation getRunAnimation(final AnimationState animationState) {
        switch(animationState){
            case ARMOUR_EQUIPPED:
                return armourRunAnimation;
            case ARMOUR_AND_GUN_EQUIPPED:
                return armourRunGunAnimation;
            case GUN_EQUIPPED:
                return runGunAnimation;
            default:
                return getDefaultAnimation();
        }
    }

    private AtlasConfig getJumpAtlasConfig(final AnimationState animationState) {
        switch(animationState){
            case ARMOUR_EQUIPPED:
                return armourJumpAtlasConfig;
            case ARMOUR_AND_GUN_EQUIPPED:
                return armourJumpGunAtlasConfig;
            case GUN_EQUIPPED:
                return jumpGunAtlasConfig;
            default:
                return jumpAtlasConfig;
        }
    }

    private Animation getJumpAnimation(final AnimationState animationState) {
        switch(animationState){
            case ARMOUR_EQUIPPED:
                return armourJumpAnimation;
            case ARMOUR_AND_GUN_EQUIPPED:
                return armourJumpGunAnimation;
            case GUN_EQUIPPED:
                return jumpGunAnimation;
            default:
                return jumpAnimation;
        }
    }

    private void drawUpgradingAnimation(Batch batch, AnimationState animationState) {
        final Animation animation;
        final TextureRegion region;
        final PositionConfig positionConfig = this.runnerConfig.getPosition();
        final Vector2 defaultPosition = new Vector2(positionConfig.getX(), positionConfig.getY());
        final AtlasConfig atlasConfig = getAtlasConfig(animationState);

        this.setForcedPositionVector(Optional.of(defaultPosition));
        maintainPosition();
        animation = getUpgradingAnimation(animationState);
        region = animation.getKeyFrame(stateTime, true);
        drawAnimation(batch,
                region,
                Optional.of(atlasConfig.getImageOffset()),
                Optional.of(atlasConfig.getImageScale()));
    }

    private AtlasConfig getAtlasConfig(AnimationState animationState) {
        switch(animationState){
            case ARMOUR_EQUIPPED:
                return armourRunGunAtlasConfig;
            default:
                return armourRunAtlasConfig;
        }
    }

    private Animation getUpgradingAnimation(final AnimationState animationState) {
        switch(animationState){
            case ARMOUR_EQUIPPED:
                return armourRunGunAnimation;
            case GUN_EQUIPPED:
                return runGunAnimation;
            default:
                return this.getDefaultAnimation();
        }
    }

    private Animation getSlideAnimation(final AnimationState animationState) {

        switch(animationState){
            case ARMOUR_EQUIPPED:
                return armourSlideAnimation;
            case ARMOUR_AND_GUN_EQUIPPED:
                return armourSlideGunAnimation;
            case GUN_EQUIPPED:
                return slideGunAnimation;
            default:
                return slideAnimation;
        }

    }

    public void resetPosition(){
        final Filter f = new Filter();
        f.categoryBits = Constants.RUNNER_RUNNING_CATEGORY;
        f.groupIndex = Constants.RUNNER_RUNNING_GROUP_INDEX;
        f.maskBits = Constants.RUNNER_RUNNING_MASK_INDEX;
        final Body body = this.getBody();
        if(body!=null) {
            final Array<Fixture> fixtureList = body.getFixtureList();
            if(fixtureList != null && fixtureList.size > 0) {
                fixtureList.get(0).setFilterData(f);
            }
            body.setTransform(Box2dFactory.getInstance().getRunPosition(), 0f);
        }
    }

    private void scheduleDeath(final Body body) {
        if(!deathScheduled) {
            final HitVectorConfig hitVectorConfig = runnerConfig.getHitVectorConfig();
            Timer.schedule(new Timer.Task() {
                @Override
                public void run() {
                    final float hitVelocityX = hitVectorConfig.getHitVelocityX();
                    final float hitVelocityY = hitVectorConfig.getHitVelocityY();
                    final float hitImpulseX = hitVectorConfig.getHitImpulseX();
                    final float hitImpulseY = hitVectorConfig.getHitImpulseY();
                    final Filter f = createDeathCollisionFilter();
                    final Vector2 linearVelocity = new Vector2(hitVelocityX, hitVelocityY);
                    final Vector2 impulseVector = new Vector2(hitImpulseX, hitImpulseY);
                    final Optional<Float> rotationOptional = Optional.absent();
                    final CollisionParams collisionParams = new CollisionParams(
                            linearVelocity, impulseVector, f, body, rotationOptional);
                    applyCollisionImpulse(collisionParams);
                    clearTransform();
                }
            }, hitVectorConfig.getHitPauseTime());
            deathScheduled = true;
        }
    }

    @Subscribe
    public void onBossDead(BossDeadEvent bossDeadEvent){

        final PositionConfig endOfLevelPosition = this.runnerConfig.getEndOfLevelPosition();
        final float endVelocityX = this.runnerConfig.getEndOfLevelVelocityX();
        final float endVelocityY = this.runnerConfig.getEndOfLevelVelocityY();
        moveToPosition(endOfLevelPosition, endVelocityX, endVelocityY);

    }

    private void moveToPosition(PositionConfig position, float endVelocityX, float endVelocityY) {
        this.setEndOfLevelPosition(Optional.fromNullable(position));
        this.setForcedLinearVelocity(endVelocityX, endVelocityY);
        this.setAnimationState(AnimationState.DEFAULT);
    }

    @Override
    public void act(float delta) {
        super.act(delta);
        if(collidedWithDeadBoss){
            Events.get().post(new RunnerEndLevelEvent());
            Box2dFactory.destroyAndRemove(this);
        } else {
            if (endOfLevelPosition.isPresent()) {
                if (this.getBody().getPosition().x >= endOfLevelPosition.get().getX()) {
                    clearForcedLinearVelocity();
                    this.collidedWithDeadBoss = false;
                    this.destroyOnNextCollision = true;
                    jump(null);
                    //maintainPosition();
                }
            }
        }
    }

    private Filter createDeathCollisionFilter() {
        final Filter f = new Filter();
        f.categoryBits = Constants.RUNNER_HIT_CATEGORY;
        f.groupIndex = Constants.RUNNER_HIT_GROUP_INDEX;
        f.maskBits = Constants.RUNNER_HIT_MASK_INDEX;
        return f;
    }

    private void clearTransform() {
        final Optional<Vector2> noTransform = Optional.absent();
        this.setForcedTransform(noTransform);
    }

    private void drawSlideAnimation(Batch batch, TextureRegion textureRegion) {
        final Rectangle textureBounds = this.getTextureBounds();
        float x = textureBounds.x;
        float y = textureBounds.y;
        //swap width and height
        float width = textureBounds.getHeight();
        float height = textureBounds.getWidth();
        final Optional<ImageOffsetConfig> offsetOptional =
                Optional.fromNullable(this.slideAtlasConfig.getImageOffset());
        final Optional<ImageScaleConfig> scaleOptional =
                Optional.fromNullable(this.slideAtlasConfig.getImageScale());

        if(offsetOptional.isPresent()){
            final ImageOffsetConfig imageOffsetConfig = offsetOptional.get();
            x += imageOffsetConfig.getX();
            y += imageOffsetConfig.getY();
        }
        if(scaleOptional.isPresent()){
            final ImageScaleConfig imageScaleConfig = scaleOptional.get();
            width *= imageScaleConfig.getX();
            height *= imageScaleConfig.getY();
        }
        batch.draw(textureRegion, x, y, width, height);
    }

    @Subscribe
    public void beginContact(BeginContactEvent beginContactEvent){

        if(destroyOnNextCollision){
            collidedWithDeadBoss = true;
            return;
        } else {
            final Optional<RunnerActor> runnerActorOptional = beginContactEvent.getRunnerActor();
            final Optional<EnemyActor> enemyActorOptional = beginContactEvent.getEnemyActor();
            final Optional<GroundActor> groundActorOptional = beginContactEvent.getGroundActor();
            final Optional<ArmourActor> armourActorOptional = beginContactEvent.getArmourActor();
            final Optional<GunActor> gunActorOptional = beginContactEvent.getGunActor();
            for (RunnerActor runnerActor : runnerActorOptional.asSet()) {
                final ActorState actorState = this.getActorState();
                for (EnemyActor enemyActor : enemyActorOptional.asSet()) {
                    if (!actorState.equals(ActorState.HIT)) {
                        this.hit(enemyActor);
                    }
                }
                for (ArmourActor armourActor : armourActorOptional.asSet()) {
                    if (!actorState.equals(ActorState.HIT)) {
                        this.pickupArmour();
                    }
                }
                for (GunActor gunActor : gunActorOptional.asSet()) {
                    if (!actorState.equals(ActorState.HIT)) {
                        this.pickupGun();
                    }
                }
                for (GroundActor groundActor : groundActorOptional.asSet()) {
                    this.setLanded();
                }
            }
        }

    }

    private void pickupArmour() {
        Events.get().post(new ArmourPickedUpEvent());
        this.setActorState(ActorState.UPGRADING_ARMOUR);
        Timer.schedule(new Timer.Task() {
            @Override
            public void run() {
                if(getAnimationState().equals(AnimationState.GUN_EQUIPPED)){
                    setAnimationState(AnimationState.ARMOUR_AND_GUN_EQUIPPED);
                } else {
                    setAnimationState(AnimationState.ARMOUR_EQUIPPED);
                }
                unMaintainPosition();
                clearTransform();
                setActorState(ActorState.RUNNING);
                resetPosition();
                getBody().setLinearVelocity(0f, 0f);
            }
        }, 0.1f);
    }

    private void pickupGun() {
        Events.get().post(new GunPickedUpEvent());
        this.setActorState(ActorState.UPGRADING_GUN);
        Timer.schedule(new Timer.Task() {
            @Override
            public void run() {
                if(getAnimationState().equals(AnimationState.ARMOUR_EQUIPPED)) {
                    setAnimationState(AnimationState.ARMOUR_AND_GUN_EQUIPPED);
                } else {
                    setAnimationState(AnimationState.GUN_EQUIPPED);
                }
                unMaintainPosition();
                clearTransform();
                setActorState(ActorState.RUNNING);
                resetPosition();
                getBody().setLinearVelocity(0f, 0f);
            }
        }, 0.1f);
    }

    @Subscribe
    public void jump(JumpControlInvokedEvent jumpControlInvokedEvent) {
        if (canJump()) {
            if(this.getActorState().equals(ActorState.SLIDING)){
                this.stopSliding();
                Timer.schedule(new Timer.Task(){
                    @Override
                    public void run() {
                        applyJump();
                        setActorState(ActorState.JUMPING);
                    }
                },0.1f);
            }else {
                applyJump();
                setActorState(ActorState.JUMPING);
            }
        }
    }

    private void applyJump() {
        final Body body = getBody();
        final Vector2 runnerLinerImpulse = Box2dFactory.getInstance().getRunnerJumpImpulse();
        body.applyLinearImpulse(runnerLinerImpulse,
                body.getWorldCenter(), true);
    }

    @Subscribe
    public void slide(SlideControlInvokedEvent slideControlInvokedEvent){
        if( canSlide() ){
            if(!getActorState().equals(ActorState.SLIDING)) {
                final Body body = getBody();
                body.setTransform(Box2dFactory.getInstance().getSlidePosition(),
                        Box2dFactory.getInstance().getSlideAngle());
                maybeUpdateTextureBounds();
                scheduleStopSliding();
                setActorState(ActorState.SLIDING);
            }
        }
    }

    private void scheduleStopSliding() {
        Timer.schedule(new Timer.Task() {
            @Override
            public void run() {
                if (getActorState().equals(ActorState.SLIDING)) {
                    stopSliding();
                }
            }
        }, this.runnerConfig.getSlideTime());
    }

    public void stopSliding(){
        if(canSlide()) {
            final Body body = getBody();
            body.setTransform(Box2dFactory.getInstance().getRunPosition(), 0f);
            maybeUpdateTextureBounds();
            setActorState(ActorState.RUNNING);
        }
   }

    public void hit(final EnemyActor enemyActor) {

        if(enemyActor.getActorState().equals(ActorState.HIT_BY_ARMOUR))
            return;

        if(enemyActor instanceof EnemyBulletActor){
            if(getAnimationState().equals(AnimationState.ARMOUR_EQUIPPED)) {
                return;
            }
        }

        killRunner();

    }

    private void killRunner() {
        final Body body = getBody();
        setActorState(ActorState.HIT);
        scheduleDeath(body);
        Events.get().post(new RunnerHitEvent(this));
    }

    public boolean canJump(){
        final ActorState state = this.getActorState();
        return !(state.equals(ActorState.JUMPING) ||
                state.equals(ActorState.HIT) ||
                state.equals(ActorState.FALLING));
    }

    public boolean canSlide(){
        final ActorState state = this.getActorState();
        return !(state.equals(ActorState.JUMPING) ||
                state.equals(ActorState.HIT) ||
                state.equals(ActorState.FALLING));
    }

    public void setLanded() {
        final ActorState state = this.getActorState();
        if(!(state.equals(ActorState.HIT) || state.equals(ActorState.FALLING)))
            setActorState(ActorState.RUNNING);
    }

    public void setAnimationState(AnimationState animationState) {
        this.animationState = animationState;
    }

    public AnimationState getAnimationState() {
        return animationState;
    }

    public void setEndOfLevelPosition(Optional<PositionConfig> endOfLevelPosition) {
        this.endOfLevelPosition = endOfLevelPosition;
    }

    public Optional<PositionConfig> getEndOfLevelPosition() {
        return endOfLevelPosition;
    }
}


text:
NodeJS Radius Server

# Prerequisites
Install latest NodeJS and NPM (comes with nodejs installer) from https://nodejs.org/en/download/

# How to run
1. Clone the repository

`git clone git@github.com:chiradip/NodeRadius.git`

2. Change to NodeRadius directory

`cd NodeRadius`

3. Install the dependencies

`npm install`

4. Start the Radius Server

`npm start`

redpajama_set_name: RedPajamaGithub


text:
window.InfinniUI = window.InfinniUI || {};
window.InfinniUI.config = window.InfinniUI.config || {};
window.InfinniUI.config.lang = 'en-US';

window.InfinniUI.config.useLoaderIndicator = true;

window.InfinniUI.config.serverUrl = 'http://e.armagames.org/api'
window.InfinniUI.config.configName = 'Eruditor.Next';

window.InfinniUI.config.homePage = 'views/main.json';
window.InfinniUI.config.Routes = [];


text:
Notes, slides, and examples for the BMI tutorial for the 2015 CSDMS annual meeting.

To view the IPython notebooks with nbviewer, point your browser [here](http://nbviewer.ipython.org/github/mcflugen/bmi-tutorial/blob/master/notebooks/index.ipynb),

    http://nbviewer.ipython.org/github/mcflugen/bmi-tutorial/blob/master/notebooks/index.ipynb


text:
.class public final Landroid/hardware/hdmi/HdmiHotplugEvent;
.super Ljava/lang/Object;
.source "HdmiHotplugEvent.java"

# interfaces
.implements Landroid/os/Parcelable;

# static fields
.field public static final CREATOR:Landroid/os/Parcelable$Creator;
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "Landroid/os/Parcelable$Creator",
            "<",
            "Landroid/hardware/hdmi/HdmiHotplugEvent;",
            ">;"
        }
    .end annotation
.end field

# instance fields
.field private final mConnected:Z

.field private final mPort:I

# direct methods
.method static constructor <clinit>()V
    .locals 1

    .prologue
    .line 86
    new-instance v0, Landroid/hardware/hdmi/HdmiHotplugEvent$1;

    invoke-direct {v0}, Landroid/hardware/hdmi/HdmiHotplugEvent$1;-><init>()V

    sput-object v0, Landroid/hardware/hdmi/HdmiHotplugEvent;->CREATOR:Landroid/os/Parcelable$Creator;

    return-void
.end method

.method public constructor <init>(IZ)V
    .locals 0
    .param p1, "port"    # I
    .param p2, "connected"    # Z

    .prologue
    .line 41
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    .line 42
    iput p1, p0, Landroid/hardware/hdmi/HdmiHotplugEvent;->mPort:I

    .line 43
    iput-boolean p2, p0, Landroid/hardware/hdmi/HdmiHotplugEvent;->mConnected:Z

    .line 44
    return-void
.end method

# virtual methods
.method public describeContents()I
    .locals 1

    .prologue
    .line 70
    const/4 v0, 0x0

    return v0
.end method

.method public getPort()I
    .locals 1

    .prologue
    .line 52
    iget v0, p0, Landroid/hardware/hdmi/HdmiHotplugEvent;->mPort:I

    return v0
.end method

.method public isConnected()Z
    .locals 1

    .prologue
    .line 61
    iget-boolean v0, p0, Landroid/hardware/hdmi/HdmiHotplugEvent;->mConnected:Z

    return v0
.end method

.method public writeToParcel(Landroid/os/Parcel;I)V
    .locals 1
    .param p1, "dest"    # Landroid/os/Parcel;
    .param p2, "flags"    # I

    .prologue
    .line 82
    iget v0, p0, Landroid/hardware/hdmi/HdmiHotplugEvent;->mPort:I

    invoke-virtual {p1, v0}, Landroid/os/Parcel;->writeInt(I)V

    .line 83
    iget-boolean v0, p0, Landroid/hardware/hdmi/HdmiHotplugEvent;->mConnected:Z

    if-eqz v0, :cond_0

    const/4 v0, 0x1

    :goto_0
    int-to-byte v0, v0

    invoke-virtual {p1, v0}, Landroid/os/Parcel;->writeByte(B)V

    .line 84
    return-void

    .line 83
    :cond_0
    const/4 v0, 0x0

    goto :goto_0
.end method


text:
/***********************************************************************
	created:    Sat Mar 12 2005
	author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/

#ifndef XMLATTRIBUTE_H
#define XMLATTRIBUTE_H

#include <duilib2_global.h>
#include <map>

namespace duilib2
{

/**
 * @brief
 *     Class representing a block of attributes associated with an XML element.
 */
class DUILIB2SHARED_EXPORT XmlAttributes
{
public:
	XmlAttributes();
	~XmlAttributes();

	/**
	 * @brief
	 *     Add an attribute to the attribute block. if the attribute value already exists,
	 *     it is replaced with the new value.
	 *
	 * @param name
	 *     String object holding the name of the attributes to be added.
	 *
	 * @param value
	 *     String object holding a string representation of the attribute value.
	 */
	void add(const String& name, const String& value);

	/**
	 * @brief
	 *     Removes an attribute from the attribute block.
	 *
	 * @param name
	 *     The name of the attribute to be removed.
	 */
	void remove(const String& name);

	/**
	 * @brief
	 *     Return whether the named attribute exists within the attribute block.
	 *
	 * @param name
	 *     The name of the attribute to be checked.
	 *
	 * @return
	 *     - true if an attribute with the name \a name is present in the attribute block.
	 *     - false if no attribute named \a name is present in the attribute block.
	 */
	bool exists(const String& name) const;

	/**
	 * @brief
	 *     Return the number of attributes in the attribute block.
	 *
	 * @return
	 *     value specifying the number of attributes in this attribute block.
	 */
	int getCount() const;

	/**
	 * @brief
	 *     Return the name of an attribute based upon its index within the attribute block.
	 *
	 * @param index
	 *     Zero based index of the attribute whos name is to be returned.
	 *
	 * @return
	 *     The name of the attribute at the requested index.
	 */
	String getName(int index) const;

	/**
	 * @brief
	 *     Return the value string of the attribute based upon its index within the attribute block.
	 *
	 * @param index
	 *     Zero based index of the attribute whos name is to be returned.
	 *
	 * @return
	 *     The name of the attribute at the requested index.
	 */
	String getValue(int index) const;

	/**
	 * @brief
	 *     Return the value string for attribute \a name.
	 *
	 * @param name
	 *     The name of the attribute whos value string is to be returned.
	 *
	 * @return
	 *     The value string for attribute \a name.
	 */
	String getValue(const String& name) const;

private:
	typedef std::map<String, String> AttributeMap;
	AttributeMap mAttributes;
};

}

#endif // XMLATTRIBUTE_H


text:
package hb2

import (
	"encoding/json"
	"errors"
	"net/http"
	"net/http/httptest"
	"net/url"
	"reflect"
	"strings"
	"testing"
	"time"

	"golang.org/x/net/context"

	"github.com/remind101/pkg/reporter"
)

func TestHb2IsReporter(t *testing.T) {
	var _ reporter.Reporter = NewReporter(Config{})
}

func TestHb2ReportsErrorContext(t *testing.T) {
	h := newFakeHoneybadgerHandler(t)
	ts := httptest.NewServer(h)
	defer ts.Close()
	r := NewReporter(Config{Endpoint: ts.URL})

	boom := errors.New("The Error")
	tests := []struct {
		name string
		err  error
		path string
		want map[string]interface{}
	}{
		{
			name: "error with context",
			err: &reporter.Error{
				Err: boom,
				Context: map[string]interface{}{
					"lol": "wut",
				},
			},
			path: "request.context",
			want: map[string]interface{}{
				"lol": "wut",
			},
		},
		{
			name: "error during request",
			err: &reporter.Error{
				Err: boom,
				Context: map[string]interface{}{
					"request_id": "1234",
				},
				Request: func() *http.Request {
					form := url.Values{}
					form.Add("param1", "param1value")
					req, _ := http.NewRequest("GET", "/api/foo", nil)
					req.Header.Set("Content-Type", "application/json")
					req.Header.Set("X-Forwarded-For", "127.0.0.1")
					req.Header.Set("Authorization", "Basic shouldnotseeit")
					req.Form = form
					return req
				}(),
			},
			path: "request",
			want: map[string]interface{}{
				"cgi_data": map[string]interface{}{
					"HTTP_CONTENT_TYPE":    "application/json",
					"HTTP_X_FORWARDED_FOR": "127.0.0.1",
					"REQUEST_METHOD":       "GET",
				},
				"context": map[string]interface{}{
					"request_id": "1234",
				},
				"params": map[string]interface{}{
					"param1": []interface{}{
						"param1value",
					},
				},
				"url": "/api/foo",
			},
		},
	}

	for _, tt := range tests {
		r.Report(context.Background(), tt.err)

		select {
		case v := <-h.LastRequestBodyChan:
			got, want := atPath(v, tt.path), tt.want
			if !reflect.DeepEqual(got, want) {
				jsonGot, _ := json.MarshalIndent(got, "", "  ")
				jsonWant, _ := json.MarshalIndent(want, "", "  ")
				t.Errorf("[%s]\n got %s\nwant %s", tt.name, jsonGot, jsonWant)
			}
		case <-time.After(3 * time.Second):
			t.Fatalf("did not report to HB in 3 seconds")
		}
	}

}

func newFakeHoneybadgerHandler(t *testing.T) *fakeHoneybadgerHandler {
	return &fakeHoneybadgerHandler{make(chan map[string]interface{}, 1), t}
}

type fakeHoneybadgerHandler struct {
	LastRequestBodyChan chan map[string]interface{}
	T                   *testing.T
}

func (h *fakeHoneybadgerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	v := map[string]interface{}{}
	err := decoder.Decode(&v)
	if err != nil {
		h.T.Fatalf("not a valid json in request to Honeybadger")
	}
	h.LastRequestBodyChan <- v
	w.WriteHeader(http.StatusCreated)
}

func atPath(v map[string]interface{}, path string) map[string]interface{} {
	for _, p := range strings.Split(path, ".") {
		if p != "" {
			v = v[p].(map[string]interface{})
		}
	}
	return v
}


text:
using System;

namespace Ifp.Validation
{
    /// <summary>
    /// <see cref="ValidationSeverity"/> is the base class for the description of the <see cref="ValidationOutcome.Severity"/> of a <see cref="ValidationOutcome"/>.
    /// The severity describes how fatal the result of a validation is. There are four predefined severity levels, but you can also create your own by inheriting from this class.
    /// The predefined severity levels are
    /// <list type="definition">
    ///     <item>
    ///         <term>
    ///             <see cref="ValidationSeverity.Success"/>
    ///         </term>
    ///         <description>
    ///             The validation was successful (e.g. A required field was filled).
    ///         </description>
    ///     </item>
    ///     <item>
    ///         <term>
    ///             <see cref="ValidationSeverity.Information"/>
    ///         </term>
    ///         <description>
    ///             The validation was successful but the user should be informed about problems that were found during the validation (e.g.
    ///             The birth date you entered indicates that you are under age. You will not be able to use our payed services.)
    ///         </description>
    ///     </item>
    ///     <item>
    ///         <term>
    ///             <see cref="ValidationSeverity.Warning"/>
    ///         </term>
    ///         <description>
    ///             The validation found a violation that might be a problem. The user should decide whether he wants to continue or cancel the process (e.g.
    ///             The item you purchased are overweight. Additional shipping charges apply.)
    ///         </description>
    ///     </item>
    ///     <item>
    ///         <term>
    ///             <see cref="ValidationSeverity.Error"/>
    ///         </term>
    ///         <description>
    ///             The validation failed. The error is reported to the user and the process is canceled.
    ///             (e.g. The email address you entered is invalid.)
    ///         </description>
    ///     </item>
    /// </list>
    /// </summary>
    public abstract class ValidationSeverity : IComparable<ValidationSeverity>
    {
        static readonly SuccessSeverity _Success = new SuccessSeverity();
        static readonly InformationSeverity _Information = new InformationSeverity();
        static readonly WarningSeverity _Warning = new WarningSeverity();
        static readonly ErrorSeverity _Error = new ErrorSeverity();

        /// <summary>
        /// If <c>true</c> the process will be canceled in any case.
        /// </summary>
        public abstract bool CausesCancel { get; }

        /// <summary>
        /// If <c>true</c> the process can be canceled by the user.
        /// </summary>
        public abstract bool AllowsCancel { get; }

        /// <summary>
        /// Returns a number to allow comparison between <see cref="ValidationSeverity">validation severities</see>. This number is used by the
        /// <see cref="ValidationSummary"/> to calculate the <see cref="ValidationSummary.Severity"/> by looking for the highest severity of all <see cref="ValidationOutcome"/>.
        /// </summary>
        protected abstract int SeverityAsNumber { get; }

        /// <summary>
        /// If <c>true</c> the severity will be treated as an error and will be presented to the user.
        /// This is true for all severities except <see cref="ValidationSeverity.Success"/>.
        /// </summary>
        public virtual bool IsAnError => true;

        /// <summary>
        /// One of the default severities. Returns a instance of <see cref="SuccessSeverity"/>.
        /// </summary>
        public static SuccessSeverity Success => _Success;

        /// <summary>
        /// One of the default severities. Returns a instance of <see cref="InformationSeverity"/>.
        /// </summary>
        public static InformationSeverity Information => _Information;

        /// <summary>
        /// One of the default severities. Returns a instance of <see cref="WarningSeverity"/>.
        /// </summary>
        public static WarningSeverity Warning => _Warning;

        /// <summary>
        /// One of the default severities. Returns a instance of <see cref="ErrorSeverity"/>.
        /// </summary>
        public static ErrorSeverity Error => _Error;

        /// <summary>
        /// A default severity. The <see cref="SuccessSeverity"/> indicates that an object conforms to a validation rule.
        /// </summary>
        public sealed class SuccessSeverity : ValidationSeverity
        {
            /// <summary>
            /// Returns <c>false</c>. Should be ignored because <see cref="IsAnError"/> is <c>false</c>.
            /// </summary>
            public override bool AllowsCancel => false;

            /// <summary>
            /// Returns <c>false</c>. Should be ignored because <see cref="IsAnError"/> is <c>false</c>.
            /// </summary>
            public override bool CausesCancel => false;

            /// <summary>
            /// Returns <c>false</c> indicating a validation success.
            /// </summary>
            public override bool IsAnError => false;

            /// <summary>
            /// Returns <c>0</c>. Lowest severity.
            /// </summary>
            protected override int SeverityAsNumber => 0;
        }

        /// <summary>
        /// A default severity. The <see cref="InformationSeverity"/> indicates that an object conforms to a validation rule, but the user should be
        /// informed about something.
        /// </summary>
        public class InformationSeverity : ValidationSeverity
        {
            /// <summary>
            /// Returns <c>false</c>. The user should only be informed. To allow cancellation use <see cref="WarningSeverity"/> instead.
            /// </summary>
            public override bool AllowsCancel => false;

            /// <summary>
            /// Returns <c>false</c>. Information allows continuation of the process.
            /// </summary>
            public override bool CausesCancel => false;

            /// <summary>
            /// Returns <c>10</c>.
            /// </summary>
            protected override int SeverityAsNumber => 10;
        }

        /// <summary>
        /// A default severity. The <see cref="WarningSeverity"/> indicates that an object violates a validation rule, but the user should #
        /// decide whether the process should be continued or canceled.
        /// </summary>
        public class WarningSeverity : ValidationSeverity
        {

            /// <summary>
            /// Returns <c>true</c> to enable cancellation.
            /// </summary>
            public override bool AllowsCancel => true;

            /// <summary>
            /// Returns <c>false</c> to allow continuation of the process.
            /// </summary>
            public override bool CausesCancel => false;

            /// <summary>
            /// Returns <c>20</c>.
            /// </summary>
            protected override int SeverityAsNumber => 20;
        }

        /// <summary>
        /// A default severity. The <see cref="ErrorSeverity"/> indicates that an object violates a validation rule and the
        /// process should be canceled.
        /// </summary>
        public class ErrorSeverity : ValidationSeverity
        {
            /// <summary>
            /// Returns <c>true</c>.
            /// </summary>
            public override bool AllowsCancel => true;

            /// <summary>
            /// Returns <c>true</c>. This disallows the continuation of the process.
            /// </summary>
            public override bool CausesCancel => true;

            /// <summary>
            /// Returns <c>30</c>.
            /// </summary>
            protected override int SeverityAsNumber => 30;
        }

        /// <summary>
        /// Implements <see cref="IComparable{T}"/>. Compares two <see cref="ValidationSeverity"/> objects by delegating to <see cref="SeverityAsNumber"/>.
        /// </summary>
        /// <param name="other">The other <see cref="ValidationSeverity"/> to compare to.</param>
        /// <returns>Returns a number indicating smaller, greater or equals as described by <see cref="IComparable{T}"/>.</returns>
        public virtual int CompareTo(ValidationSeverity other) => this.SeverityAsNumber.CompareTo(other.SeverityAsNumber);
    }
}