(function($) {
    $.fn.sc2build = function(options) {
        var opts = $.extend({}, $.fn.sc2build.defaults, options);
        this.data('race', new $.fn.sc2build.race(opts.build[0]));
        var unit_selector = '';
        for(var i in this.data('race').units) {
            unit_selector += '<span class="'+i+'">'+
                this.data('race').get_unit(i).name+
            '</span><br />';
        }
        this.append(
            '<table class="build_table">'+
                '<thead>'+
                    '<tr>'+
                        '<th>Time</th>'+
                        '<th>Minerals</th>'+
                        '<th>Supply</th>'+
                        '<th>Army</th>'+
                        '<th>Action</th>'+
                    '</tr>'+
                '</thead>'+
                '<tfoot>'+
                    '<tr><td colspan="5">'+
                        unit_selector+
                    '</td></tr>'+
                '</tfoot>'+
                '<tbody></tbody>'+
            '</table>'
        );
        
        this.find('tfoot span').click(function() {
            window.location = window.location.href + $(this).attr('class');
            var sc2build = $($(this).parents('div.sc2build').get(0))
            sc2build.data('build_order')
                .add_unit(sc2build.data('race').get_unit($(this).attr('class')));
            sc2build.sc2builddisplay();
        });
        
        this.data('build_order', new $.fn.sc2build.build_order(opts.build[0]));
        
        this.data('build_order').force_unit(this.data('race').get_unit('a'), 0);
        this.data('build_order').force_unit(this.data('race').get_unit('A'), 0);
        this.data('build_order').force_unit(this.data('race').get_unit('A'), 0);
        this.data('build_order').force_unit(this.data('race').get_unit('A'), 0);
        this.data('build_order').force_unit(this.data('race').get_unit('A'), 0);
        this.data('build_order').force_unit(this.data('race').get_unit('A'), 0);
        this.data('build_order').force_unit(this.data('race').get_unit('A'), 0);
        
        opts.build = opts.build.substr(1).split('');
        
        for(var i in opts.build) {
            this.data('build_order').add_unit(this.data('race').get_unit(opts.build[i]));
        }
        
        this.sc2builddisplay();
    }
    
    $.fn.sc2builddisplay = function() {
        var tbody = this.find('tbody');
        tbody.html('');
        for (var i in this.data('build_order').build_order) {
            instant = this.data('build_order').build_order[i];
            tbody.append($(
                '<tr>'+
                    '<td rowspan="' + instant[1].length + '">'+instant[0]+'</td>'+
                    '<td rowspan="' + instant[1].length + '">'+
                        this.data('build_order').get_unspent_minerals(instant[0])+
                    '</td>'+
                    '<td rowspan="' + instant[1].length + '">'+
                        this.data('build_order').get_used_supply(instant[0])+
                        ' / '+
                        this.data('build_order').get_total_supply(instant[0])+
                    '</td>'+
                    '<td rowspan="' + instant[1].length + '">'+
                        this.data('build_order').get_army(instant[0])+
                    '</td>'+
                    '<td>'+instant[1][0].name+
                    '</td>'+
                +'</tr>'
            ));
            
            
            
            for(var j = 1; j < instant[1].length; ++j) {
                tbody.append($(
                    '<tr>'+
                        '<td>'+instant[1][j].name+'</td>'+
                    '</tr>'
                ));
            }
        }
    }
    
    $.fn.sc2build.race = function(race) {
        switch(race) {
            case 'P':
                this.units = $.fn.sc2build.protoss;
                break;
            case 'T':
                this.units = $.fn.sc2build.terran;
                break;
            case 'Z':
                this.units = $.fn.sc2build.zerg;
                break;
        }
    }
    
    $.fn.sc2build.race.prototype.init_build = function() {
        return 'test';
    }
    
    $.fn.sc2build.race.prototype.get_unit = function(char) {
        return eval('this.units.'+char);
    }
    
    $.fn.sc2build.build_order = function() {
    }
    
    $.fn.sc2build.build_order.prototype.build_order = [];
    
    $.fn.sc2build.build_order.prototype.add_unit = function(unit) {
        var time = this.build_order[this.build_order.length-1][0];
        
        time = time > 0 ? time : 1;
        
        while( ! this.can_build(unit, time)) {
            time += 1;
        }
        
        this.build_order[this.find_time(time)][1].push(unit);
    }
    
    $.fn.sc2build.build_order.prototype.can_build = function(unit, time) {
        return this.get_unspent_minerals(time) >= unit.mineral_cost &&
            (this.get_total_supply(time) - this.get_used_supply(time)) >= unit.supply_cost;
    }
    
    $.fn.sc2build.build_order.prototype.force_unit = function(unit, time) {
        var temp_unit = {
            name : unit.name,
            time : 0,
            mineral_cost : 0,
            mineral_gen : unit.mineral_gen,
            supply_gen : unit.supply_gen,
            supply_cost : unit.supply_cost,
        }
        this.build_order[this.find_time(time)][1].push(temp_unit);
    }
    
    $.fn.sc2build.build_order.prototype.find_time = function(time) {
        for(var i in this.build_order) {
            if(this.build_order[i][0] == time)
            return i;
        }
        
        this.build_order.push(new Array(Number(time), []));
        return this.build_order.length - 1;
    }
    
    $.fn.sc2build.build_order.prototype.get_unspent_minerals = function(time) {
        var minerals = 50;
        
        for(var i in this.build_order) {
            var curr_time = this.build_order[i][0];
            if(curr_time > time) break;
            for(var j in this.build_order[i][1]) {
                var unit = this.build_order[i][1][j];
                var mineral_gen = (time - (curr_time + unit.time)) * unit.mineral_gen  / 60;
                minerals += mineral_gen > 0 ? mineral_gen: 0;
                minerals -= unit.mineral_cost;
            }
        }
        
        return Math.floor(minerals);
    }
    
    $.fn.sc2build.build_order.prototype.get_used_supply = function(time) {
        var supply = 0;
        for(var i in this.build_order) {
            var curr_time = this.build_order[i][0];
            if(curr_time > time) break;
            for(var j in this.build_order[i][1]) {
                var unit = this.build_order[i][1][j];
                supply += unit.supply_cost;
            }
        }
        
        return supply;
    }
    
    $.fn.sc2build.build_order.prototype.get_total_supply = function(time) {
        var supply = 0;
        
        for(var i in this.build_order) {
            var curr_time = this.build_order[i][0];
            if(curr_time > time) break;
            for(var j in this.build_order[i][1]) {
                var unit = this.build_order[i][1][j];
                if ((curr_time + unit.time) <= time) {
                    supply += unit.supply_gen;
                }
            }
        }
        
        return supply;
    }
    
    $.fn.sc2build.build_order.prototype.get_army = function(time) {
        return '';
    }
    
    $.fn.sc2build.protoss = {
        a : { name : 'Nexus',   time : 100, mineral_cost : 400, supply_gen : 10, mineral_gen : 0,  supply_cost : 0 },
        b : { name : 'Pylon',   time : 35,  mineral_cost : 100, supply_gen : 8,  mineral_gen : 0,  supply_cost : 0 },
        c : { name : 'Gateway', time : 65,  mineral_cost : 150, supply_gen : 0,  mineral_gen : 0,  supply_cost : 0 },
        A : { name : 'Probe',   time : 17,  mineral_cost : 50,  supply_gen : 0,  mineral_gen : 50, supply_cost : 1 },
        B : { name : 'Zealot',  time : 33,  mineral_cost : 100, supply_gen : 0,  mineral_gen : 0,  supply_cost : 2 },
    };
    
    $.fn.sc2build.zerg = {
        a : { name : 'Hatchery',      time : 100, mineral_cost : 300, supply_gen : 10, mineral_gen : 0,  supply_cost : 0 },
        b : { name : 'Spawning Pool', time : 65,  mineral_cost : 200, supply_gen : 0,  mineral_gen : 0,  supply_cost : 0 },
        A : { name : 'Drone',         time : 17,  mineral_cost : 50,  supply_gen : 0,  mineral_gen : 50, supply_cost : 1 },
        B : { name : 'Overlord',      time : 25,  mineral_cost : 100, supply_gen : 8,  mineral_gen : 0,  supply_cost : 0 },
        C : { name : 'Zergling',      time : 24,  mineral_cost : 50,  supply_gen : 0,  mineral_gen : 0,  supply_cost : 1 },
    };
    
    $.fn.sc2build.terran = {
        a : { name : 'Command Center', time : 100, mineral_cost : 400, supply_gen : 11, mineral_gen : 0,  supply_cost : 0 },
        b : { name : 'Supply Depot',   time : 30,  mineral_cost : 100, supply_gen : 8,  mineral_gen : 0,  supply_cost : 0 },
        c : { name : 'Barracks',       time : 60,  mineral_cost : 150, supply_gen : 0,  mineral_gen : 0,  supply_cost : 0 },
        A : { name : 'SCV',            time : 17,  mineral_cost : 50,  supply_gen : 0,  mineral_gen : 50, supply_cost : 1 },
        B : { name : 'Marine',         time : 25,  mineral_cost : 50,  supply_gen : 0,  mineral_gen : 0,  supply_cost : 1 },
    };
    
    $.fn.sc2build.defaults = {
        build: 'P'
    }
})(jQuery);
