var writeDown = {
    delay: 110,
    add: null,
    div: document.getElementById('playArea'),
    log: function() {
        var args = arguments;
        if (args.length == 0) {
            args = [''];
        }
        var div = this.div;
        setTimeout(function() {
            //console.log(args[0]);
            div.innerHTML = args[0] + "<br/>" + div.innerHTML;
        }, this.delay);
        if (this.add == null) {
            this.add = this.delay;
        }
        this.delay += this.add;
    },

    updateDiv: function(msg, div) {
        setTimeout(function() {
            //console.log(msg, div);
            div.innerHTML = msg;
        }, this.delay);
    },

    updateDiv_delay: function(msg, div) {
        setTimeout(function() {
            document.getElementById(div).innerHTML = msg;
        }, this.delay);
    },

    updateDiv_color: function(color, div) {
        setTimeout(function() {
            //console.log(color, div);
            document.getElementById(div).style.background = color;
        }, this.delay);
    }
}


var Diamond = function(d_name, d_id) {

    var name = d_name;
    var diamond = document.getElementById(d_id);

    var bases = {
        first: false,
        second: false,
        third: false,
        home: false
    };

    var players = {
        first: false,
        second: false,
        third: false,
        home: false
    };

    this.clear = function() {
        bases = {
            first: false,
            second: false,
            third: false,
            home: false
        };
        players = {
            first: false,
            second: false,
            third: false,
            home: false
        };
        this.updateBases();
        writeDown.updateDiv('', diamond);
    }

    this.onBase = function(base_amt, PlayerName) {
        var return_runs = 0;
        switch (base_amt) {
        case 0:
            return 0;
            break;
        case 1:
            if (bases.first) {
                if (bases.second) {
                    if (bases.third) {
                        writeDown.log(name + ": BASES LOADED, " + players.third + " scored");
                        return_runs += 1;
                    }
                    else {
                        writeDown.log(name + ": BASES LOADED");
                        bases.third = true;
                    }
                    players.third = players.second;
                    players.second = players.first;
                    players.first = PlayerName;
                }
                else {
                    writeDown.log(name + ": Man on 1st and 2nd");
                    players.second = players.first;
                    players.first = PlayerName;
                    bases.second = true;
                }
            }
            else {
                writeDown.log(name + ": Man on 1st");
                players.first = PlayerName;
                bases.first = true;
            }
            break;
        case 2:
            if (bases.first) {
                writeDown.log(name + ": Man on 2nd, and Third");
                bases.first = false;
                if (bases.third) return_runs += 1;
                bases.third = true;
            }
            if (bases.second) {
                return_runs += 1;
                if (bases.third) {
                    writeDown.log(name + ": Man on 2nd, 2 runs scored (" + players.second + ", " + players.third + ")");
                    bases.third = false;
                    return_runs += 1;
                }
                else {
                    writeDown.log(name + ": Man on 2nd, run scored (" + players.second + ")");
                }
            }
            if (bases.third) {
                return_runs += 1;
                bases.third = false;
                writeDown.log(name + ": Man on 2nd, run scored (" + players.third + ")");
            }
            else {
                writeDown.log(name + ": Man on 2nd");
                bases.second = true;
            }
            players.third = players.first;
            players.second = PlayerName;
            players.first = null;
            break;
        case 3:
            if (bases.first) {
                writeDown.log(name + ": " + players.first + " Scored from 1st");
                bases.first = false;
                return_runs += 1;
            }
            if (bases.second) {
                writeDown.log(name + ": " + players.second + " Scored from 2nd");
                bases.second = false;
                return_runs += 1;
            }
            if (bases.third) {
                writeDown.log(name + ": " + players.third + " Scored from 3rd");
                return_runs += 1;
            }
            else {
                writeDown.log(name + ": Man on 3rd");
                bases.third = true;
            }
            players.third = PlayerName;
            players.second = null;
            players.first = null;
            break;
        case 4:
            if (bases.first) {
                writeDown.log(name + ": " + players.first + " Scored from 1st");
                bases.first = false;
                return_runs += 1;
            }
            if (bases.second) {
                writeDown.log(name + ": " + players.second + " Scored from 2nd");
                bases.second = false;
                return_runs += 1;
            }
            if (bases.third) {
                writeDown.log(name + ": " + players.third + " Scored from 3rd");
                bases.third = false;
                return_runs += 1;
            }
            players.third = null;
            players.second = null;
            players.first = null;
            writeDown.log(name + ": " + PlayerName + " Scored from home");
            return_runs += 1;
            break;
        }

        var man_on = "",
            base_names = ['first', 'second', 'third'];

        for (var i = 0; i < 4; i++) {
            if (players[base_names[i]] != null && players[base_names[i]]) {
                man_on += players[base_names[i]] + " is on " + base_names[i] + " base <br/>";
            }
        }

        writeDown.updateDiv(man_on, diamond);
        this.updateBases();
        return return_runs;
    }

    this.updateBases = function() {
        for (base in bases) {
            if (bases[base] == true) {
                writeDown.updateDiv_color('#F00', base);
            }
            else {
                writeDown.updateDiv_color('#AAA', base);
            }
        }
    }


    this.playGame = function(TeamA, TeamB, innings) {
        var score_div = document.getElementById('score');
        writeDown.updateDiv(TeamA.name + ": <span id='" + TeamA.name + "'>" + TeamA.getScore() + "</span><br/>" + TeamB.name + ": <span id='" + TeamB.name + "'>" + TeamB.getScore() + "</span><hr>" + "Outs: <span id='outs'>0</span><br/>" + "Inning: <span id='inning'>1</span>", score_div);

        for (var i = 0; i < innings; i++) {
            writeDown.log("<br/><b>INNING " + (i + 1) + "</b><br/>");
            writeDown.updateDiv_delay("Top of " + (i + 1), 'inning');
            if (TeamA.teamUp()) {
                writeDown.updateDiv_delay("Bottom of " + (i + 1), 'inning');
                writeDown.log(TeamA.name + " are out <br/>");
                this.clear();
                TeamA.resetOuts();
                writeDown.log("");
                if (TeamB.teamUp()) {
                    writeDown.log(TeamB.name + " are out<br/><br/>");
                    this.clear();
                    TeamB.resetOuts();
                    writeDown.log("");
                }
            }
        }
    }

}

var Player = function(pitcher, name) {
    var name = (name == undefined) ? "Nothing" : name;
    var balls = 0;
    var strikes = 0;

    this.getName = function() {
        return name;
    }

    this.atBat = function() {
        var pitch = pitcher.show_pitch();
        var random = Math.floor(Math.random() * 1000);
        var swing_rate = 500 - (75 * strikes);
        
        if (random < swing_rate) { //swing
            strikes += 1;
            writeDown.log(name + " swung and missed.");
            writeDown.log(name + " has " + strikes + " strikes.");
            if (strikes >= 3) {
                strikes = 0;
                balls = 0;
                writeDown.log(name + " struck out");
                return {
                    out: 1,
                    type: 0
                };
            }
        }
        else if (random < 880) { //wait for pitch
            writeDown.log(name + " watches the pitch.");
            if (pitch == "Strike") {
                strikes += 1;
                writeDown.log(name + " has " + strikes + " strikes.");
                if (strikes >= 3) {
                    strikes = 0;
                    balls = 0;
                    writeDown.log(name + " struck out");
                    return {
                        out: 1,
                        type: 0
                    };
                }
            }
            if (pitch == "Ball") {
                balls += 1;
                writeDown.log(name + " has " + balls + " balls.");
                if (balls >= 4) {
                    balls = 0;
                    strikes = 0;
                    writeDown.log(name + " has been walked");
                    return {
                        out: 0,
                        type: 1
                    };
                }
            }
        }
        else if (random <= 1000) { //hit ball
            balls = 0;
            strikes = 0;
            var hit = "Single";
            if (random > 940 && random < 970) {
                hit = "Double";
            }
            else if (random >= 970 && random < 995) {
                hit = "Triple";
            }
            else if(random >= 995){
                hit = "Homerun";
            }
            writeDown.log(name + " hit a " + hit);
            var hit_type = 1;
            if (hit == "Double") hit_type = 2;
            if (hit == "Triple") hit_type = 3;
            if (hit == "Homerun") hit_type = 4;
            writeDown.log(name + " going to base");
            return {
                out: 0,
                type: hit_type
            };
        }

        //writeDown.log(name + " waiting for next pitch");
        return this.atBat();
    }
}

var Pitcher = function(team) {
    var types = ["Ball", "Strike"];
    var Team = team;
    this.show_pitch = function() {
        var random = Math.floor(Math.random() * (types).length);
        writeDown.log();
        writeDown.log(Team.name + " pitcher threw the ball.");
        return types[random];
    }
}


var Team = function() {

    var amt_of_players = 9;
    var players = [];
    var pitcher = new Pitcher(this);
    var otherPitcher = null;
    var outs = 0;
    var score = 0;
    var stadium = null;
    var player_up_to = 0;

    this.name = "Nobody's";

    this.createTeam = function(TeamName, Opponent, Diamond) {
        stadium = Diamond;
        otherPitcher = Opponent.getPitcher();
        this.name = (TeamName == undefined) ? "Nothing" : TeamName;
        for (var i = 0; i < amt_of_players; i++) {
            players[i] = new Player(otherPitcher, "Player " + (i + 1) + " on " + this.name);
        }
        return this;
    }

    this.teamUp = function() {
        for (var i = player_up_to; i < players.length; i++) {
            var atBat = players[i].atBat();
            outs += atBat.out;
            score += stadium.onBase(atBat.type, players[i].getName());
            writeDown.updateDiv_delay(score, this.name);
            writeDown.updateDiv_delay(outs, 'outs');
            if (outs >= 3) {
                player_up_to = (i + 1) % players.length; //start with next player;
                return true;
            }
        }

        if (outs >= 3) {
            player_up_to = 0;
            return true;
        }
        else {
            player_up_to = 0;
            return this.teamUp();
        }
    }

    this.getScore = function() {
        return score;
    }

    this.resetOuts = function() {
        outs = 0;
        writeDown.updateDiv_delay(outs, 'outs');
    }

    this.getPitcher = function() {
        return pitcher;
    }
}

var TeamA = new Team();
var TeamB = new Team();
var Stadium = new Diamond("Citi Field", 'move');

TeamA.createTeam("Yankees", TeamB, Stadium);
TeamB.createTeam("Mets", TeamA, Stadium);

Stadium.playGame(TeamA, TeamB, 9);

writeDown.log("GAME OVER!");
<div id="playArea"></div>

<div id="score"></div>
<div id="move"></div>

<div id="diamond">
    <div id="d1"></div>
    <div id="first"></div>
    <div id="d2"></div>
    <div id="second"></div>
    <div id="d3"></div>
    <div id="third"></div>
    <div id="d4"></div>
    <div id="home"></div>
</div>
* {
    font-family: Lucida Console, monospace;   
    color: #FFF;
}

#playArea
{
    background-color: #000;
    height: 100%;
    overflow-y: auto;
}

#move {
    position: fixed;
    bottom: 0;
    right: 0;
    background: blue;
    width: 400px;
    height: 50px;
}

#score {
    position: fixed;
    bottom: 50px;
    right: 0;
    background: red;
    width: 200px;
    height: 80px;
    padding: 5px; 
}

div#d1 {
    width:0; height:0;
    position: fixed;
    bottom: 100px;
    right: 280px;
    line-height:0;
    border-top:25px solid transparent;
    border-right:25px solid #AAC32B;
    border-bottom:25px solid #AAC32B;
    border-left:25px solid transparent;
}

div#d2 {
    width:0; height:0;
    position: fixed;
    bottom: 100px;
    right: 230px;
    line-height:0;
    border-top:25px solid transparent;
    border-right:25px solid transparent;
    border-bottom:25px solid #AAC32B;
    border-left:25px solid #AAC32B;
}

div#d3 {
    width:0; height:0;
    position: fixed;
    bottom: 50px;
    right: 280px;
    line-height:0;
    border-top:25px solid #AAC32B;
    border-right:25px solid #AAC32B;
    border-bottom:25px solid transparent;
    border-left:25px solid transparent;
}

div#d4 {
    width:0; height:0;
    position: fixed;
    bottom: 50px;
    right: 230px;
    line-height:0;
    border-top:25px solid #AAC32B;
    border-right:25px solid transparent;
    border-bottom:25px solid transparent;
    border-left:25px solid #AAC32B;
}

div#first {
    width:10px; height:10px;
    position: fixed;
    bottom: 95px;
    right: 230px;
    background: #AAA;
    z-index: 100;
}
div#second {
    width:10px; height:10px;
    position: fixed;
    bottom: 140px;
    right: 275px;
    background: #AAA;
    z-index: 100;
}
div#third {
    width:10px; height:10px;
    position: fixed;
    bottom: 95px;
    right: 320px;
    background: #AAA;
    z-index: 100;
}