//<![CDATA[

baseHitPerLevel = {70: 96, 71: 95, 72: 94, 73: 83};
function setupTabs() {
    $('#mainTabs > ul').tabs();
}

function lookupDataFromPage() {
    lookupData($('#ch').get(0).value, $('#realm').get(0).value, $('input[@name="region"]:checked').val());
}

function lookupData(character, realm, region) {
    $('#loading').show();
    $.get(armoryScript, {'character': character, 'realm': realm, 'region': region}, 
      function(data) {
        $('#loading').hide();
        errorCode = $('result', data).attr('errorCode');
        $('#loadStatus').empty();
        if (errorCode != 0) {
            $('#loadStatus').css('display', 'block').append('Error getting armory data: ' + $('result', data).attr('errorText'));
        } else {
            $('#loadStatus').css('display', 'none');
            dataElem = $('result data', data)
            $('#frostDmg').get(0).value = dataElem.attr('frostDmg');
            $('#fireDmg').get(0).value = dataElem.attr('fireDmg');
            $('#intellect').get(0).value = dataElem.attr('intellect');
            $('#critRating').get(0).value = dataElem.attr('spellCrit');
            $('#hitRating').get(0).value = dataElem.attr('spellHit');
            $('#spellHaste').get(0).value = dataElem.attr('spellHaste');
            talentStr = dataElem.attr('talents');
            // Set the talents.
            $('#improvedFrostbolt').get(0).value = parseInt(talentStr.substr(46, 1));
            $('#elementalPrecision').get(0).value = parseInt(talentStr.substr(47, 1));
            $('#iceShards').get(0).value = parseInt(talentStr.substr(48, 1));
            $('#piercingIce').get(0).value = parseInt(talentStr.substr(52, 1));
            $('#icyVeins').get(0).value = parseInt(talentStr.substr(53, 1));
            $('#arcticWinds').get(0).value = parseInt(talentStr.substr(64, 1));
            $('#empoweredFrostbolt').get(0).value = parseInt(talentStr.substr(65, 1));
            $('#waterElemental').get(0).value = parseInt(talentStr.substr(66, 1));
            $('#arcaneConcentration').get(0).value = parseInt(talentStr.substr(5, 1));
            $('#arcaneInstability').get(0).value = parseInt(talentStr.substr(16, 1));
            $('#arcanePotency').get(0).value = parseInt(talentStr.substr(17, 1));
            $('#spellPower').get(0).value = parseInt(talentStr.substr(20, 1));
            updateCalculations();
            $('#mainTabs > ul').tabs('select', 2);
        }
      }
   );
   $('#profileLink').empty().append('<a href="http://www.wowarmory.com/character-sheet.xml?r=' + encodeURIComponent(realm) + '&n=' + encodeURIComponent(character) + '">Armory profile</a>');
}

function updateWaterElementalLine() {
    var waterElementalTP = parseInt($('#waterElemental').attr('value'));
    var includeWaterElemental = $('#includeWaterElemental').attr('checked') == true;
    if (waterElementalTP > 0 && includeWaterElemental) {
        $('#waterElementalRow').show();
    } else {
        $('#waterElementalRow').hide();
    }
}

function updateCalculations() {
    updateWaterElementalLine();
    var frostDmg = parseFloat($('#frostDmg').attr('value'));
    var fireDmg = parseFloat($('#fireDmg').attr('value'));
    var critExtraPercent = parseFloat($('#critRating').attr('value'))/22.1;
    var hitExtraPercent = parseFloat($('#hitRating').attr('value'))/12.6;
    var intellect = parseFloat($('#intellect').attr('value'));
    var spellHaste = parseFloat($('#spellHaste').attr('value'));
    if (isNaN(frostDmg)) { frostDmg = 0;}
    if (isNaN(fireDmg)) { fireDmg = 0;}
    if (isNaN(intellect)) { intellect = 0;}
    if (isNaN(critExtraPercent)) { critExtraPercent = 0;}
    if (isNaN(hitExtraPercent)) { hitExtraPercent = 0;}
    if (isNaN(spellHaste)) { spellHaste= 0;}
    var improvedFrostboltTP = parseInt($('#improvedFrostbolt').attr('value'));
    var elementalPrecisionTP = parseInt($('#elementalPrecision').attr('value'));
    var iceShardsTP = parseInt($('#iceShards').attr('value'));
    var piercingIceTP = parseInt($('#piercingIce').attr('value'));
    var icyVeinsTP = parseInt($('#icyVeins').attr('value'));
    var arcticWindsTP = parseInt($('#arcticWinds').attr('value'));
    var empoweredFrostboltTP = parseInt($('#empoweredFrostbolt').attr('value'));
    var waterElementalTP = parseInt($('#waterElemental').attr('value'));
    var arcaneConcentrationTP = parseInt($('#arcaneConcentration').attr('value'));
    var arcanePotencyTP = parseInt($('#arcanePotency').attr('value'));
    var arcaneInstabilityTP = parseInt($('#arcaneInstability').attr('value'));
    var spellPowerTP = parseInt($('#spellPower').attr('value'));
    var averageWintersChillStacks = parseInt($('#wintersChill').attr('value'));
    var moltenArmorOn = $('#moltenArmor').attr('checked') == true;
    var includeIcyVeins = $('#includeIcyVeins').attr('checked') == true;
    var includeWaterElemental = $('#includeWaterElemental').attr('checked') == true;
    critPercent = critExtraPercent + (.91 + intellect/80.0) + (moltenArmorOn ? 3.0 : 0.0) + (.02 * arcaneConcentrationTP * 10.0 * arcanePotencyTP) + arcaneInstabilityTP;
    if (critPercent > 100.0) {
        critPercent = 100.0;
    } else if (critPercent < 0.0) {
        critPercent = 0.0;
    }
    frostDmg = frostDmg * (1.0 + .01 * arcaneInstabilityTP);
    fireDmg = fireDmg * (1.0 + .01 * arcaneInstabilityTP);
    $('#critPct').empty().append(critPercent.toFixed(2));
    var mana = 2241 + 20 + (intellect - 20) * 15;
    $('#mana').empty().append(mana);
    //var frostboltSpellDmgBonus = (.95*(3.0/3.5) + .02 * empoweredFrostboltTP) * (1 - .02 * improvedFrostboltTP);
    // Patch 2.3 removed the penalty from improved frostbolt.
    var frostboltSpellDmgBonus = (.95*(3.0/3.5) + .02 * empoweredFrostboltTP);
    var frostboltCritDmgFactor = 1.0 + .5 * (1.0 + .2 * iceShardsTP + .25 * spellPowerTP);
    var fireblastCritDmgFactor = 1.0 + .5 * (1.0 + .25 * spellPowerTP); // TODO - ignite?
    var frostboltDmgBonus = (1.0 + .02 * piercingIceTP) * (1.0 + .01 * arcticWindsTP);
    // Patch 2.4 added spell haste modification to global cooldown
    var spellHasteModifier = (spellHaste / 15.7) / 100.0;
    var cooldown = 1.0 / ((1.0 + spellHasteModifier) / 1.5);
    if (cooldown < 1.0) {
        cooldown = 1.0;
    }
    $('#globalCooldown').empty().append(cooldown.toFixed(4));
    for (var lvl = 70; lvl <= 73; ++lvl) {
        var waterElementalDPS = 0.0;
        var hitPercent = Math.min(baseHitPerLevel[lvl] + elementalPrecisionTP + hitExtraPercent, 99);
        $('#hitPct' + lvl).empty().append(hitPercent.toFixed(2));
        var frostboltDmg = (623 + frostDmg * frostboltSpellDmgBonus) * frostboltDmgBonus * (hitPercent/100.0) * (1.0 + (frostboltCritDmgFactor - 1.0) * ((critPercent + empoweredFrostboltTP + (averageWintersChillStacks * 2))/100.0));
        var fireblastDmg = (735 + fireDmg * .4286) * (hitPercent/100.0) * (1.0 + ((fireblastCritDmgFactor - 1.0) * (critPercent/100.0)));
        if (includeIcyVeins && icyVeinsTP > 0) {
            // We amortize it over the full time.  20 seconds of activity and 
            // a 3 minute cooldown = active 1/9th of the time.
            // When it's active you get 20% faster casting time = 1/.8=1.25
            // times damage.
            var icyVeinsFactor = 1.0 + .25 * (1.0/9.0);
            frostboltDmg = frostboltDmg * icyVeinsFactor;
            fireblastDmg = fireblastDmg * icyVeinsFactor;
        }
        if (includeWaterElemental && waterElementalTP > 0) {
            // Again, we amortize over the entire time - active for 45 seconds
            // over 3 minutes.
            // It gets 40% of your +frost dmg, which means its waterbolt (2.5
            // second cast) gets 28.57% of +frost dmg.
            // Assuming it gets NO spell hit from you, unsure if this is true.
            // crit dmg is +50%, crit chance is 5% + what we get from winter's
            // chill.
            var waterboltDmg = (537.0 + (.2857 * frostDmg)) * (baseHitPerLevel[lvl]/100.0) * (1.0 + ((5.0 + averageWintersChillStacks * 2) / 100.0) * .5);
            var totalWaterElementalDmg = waterboltDmg * 18;
            waterElementalDPS = totalWaterElementalDmg / 180.0;
            $('#waterElementalDmg' + lvl).empty().append(waterboltDmg.toFixed(2) + " / " + waterElementalDPS.toFixed(2));
        }
        var frostboltTime = 1.0 / ((1.0 + spellHasteModifier) / (3.0 - .1 * improvedFrostboltTP));
        if (frostboltTime < cooldown) {
            // Limited by global cooldown
            frostboltTime = cooldown;
        }
        $('#frostboltTime').empty().append(frostboltTime.toFixed(2));
        $('#frostboltDmg' + lvl).empty().append(frostboltDmg.toFixed(2) + " / " + (frostboltDmg/frostboltTime).toFixed(2));
        $('#fireblastDmg' + lvl).empty().append(fireblastDmg.toFixed(2) + " / " + (fireblastDmg/cooldown).toFixed(2));
        // Figure out how many frostbolts are optimal.
        // We want to do just enough so we can fire blast when it's up.
        // Make sure fire blast dps is higher than frostbolt - if not, just
        // frostbolt all the time!
        if (frostboltDmg/frostboltTime > fireblastDmg/cooldown) {
            $('#numFrostbolts').empty().append(1);
            $('#totalDmg' + lvl).empty().append((frostboltDmg/frostboltTime + waterElementalDPS).toFixed(2));
            $('#numSeconds').empty().append(frostboltTime.toFixed(2));
            $('#fireblaston').hide();
            $('#fireblastoff').show();
        } else {
            // Fire blast's cooldown is 8 seconds.
            var numFrostboltsMin = Math.floor((8.0 - cooldown) / frostboltTime);
            var numFrostboltsMax = numFrostboltsMin + 1;
            var numFrostbolts = numFrostboltsMin;
            var numSecondsMin = cooldown + numFrostboltsMin * frostboltTime;
            // Account for the cooldown on fire blast - there is dead time in this
            // calculation, which means it's probably not optimal.  But let's
            // check anyway.
            if (numSecondsMin < 8.0) {
                numSecondsMin = 8.0;
            }
            var numSecondsMax = cooldown + numFrostboltsMax * frostboltTime;
            if (numSecondsMax < 8.0) {
                numSecondsMax = 8.0;
            }
            var totalDmgMin = (frostboltDmg*numFrostboltsMin+fireblastDmg)/numSecondsMin + waterElementalDPS;
            var totalDmgMax = (frostboltDmg*numFrostboltsMax+fireblastDmg)/numSecondsMax + waterElementalDPS;
            if (totalDmgMin > totalDmgMax) {
                $('#numFrostbolts').empty().append(numFrostboltsMin);
                $('#totalDmg' + lvl).empty().append(totalDmgMin.toFixed(2));
                $('#numSeconds').empty().append(numSecondsMin.toFixed(2));
            } else {
                $('#numFrostbolts').empty().append(numFrostboltsMax);
                $('#totalDmg' + lvl).empty().append(totalDmgMax.toFixed(2));
                $('#numSeconds').empty().append(numSecondsMax.toFixed(2));
            }
            $('#fireblaston').show();
            $('#fireblastoff').hide();
        }
    }
}

(function() {
    $(document).ready(function() {
        setupTabs();
        $(':text').keyup(updateCalculations);
        $('#loadData').click(lookupDataFromPage);
        //$('#realm').enter(lookupDataFromPage);
        $('#loadStatus').css({'display': 'none', 'color': 'red', 'background-color': 'yellow'});
        var topTalentRE = /upto(\d+)/;
        var defaultTalentRE = /default(\d+)/;
        $('select.talent').empty().each(function() {
            var topTalent = 5;
            var classNames = this.className;
            var topTalentMatch = topTalentRE.exec(classNames);
            if (topTalentMatch != null) {
                topTalent = topTalentMatch[1];
            }
            var defaultTalent = topTalent;
            var defaultTalentMatch = defaultTalentRE.exec(classNames);
            if (defaultTalentMatch != null) {
                defaultTalent = defaultTalentMatch[1];
            }
            for (var i = 0; i <= topTalent; ++i) {
                var opt = document.createElement('option');
                opt.value = i;
                opt.appendChild(document.createTextNode(i));
                this.appendChild(opt);
            }
            this.value = defaultTalent;
        });
        $('select.talent').change(updateCalculations);
        $('input.talent').click(updateCalculations);
        updateCalculations();
    });
})();

//]]>
