/* Changes:
    1.13    Quick fix for new fight screens
            Added exp average and win percentage
    1.12    Fix loot reporting in safari
    1.11    Format change on won fights
            Added target and if they are a Top Mafia Bodyguard
            Added money won/lost (if not zero)
    1.10    Added new tmp var
            Added new version check
            Added pause button
    1.09    Added specific error message and pause for the "Error while
            loading page" to differentiate it from other unknown responses.
*/
javascript:(//)
    function(){
        var version='AttackSpree 1.13',
            a, l, s, m, e, uc,
            xmlHTTP,
            app='app10979261223',
            content=$(app+'_content_row'),
            mafia_size=$("app10979261223_user_group_size").parentNode.parentNode,
            mw_url='http://apps.facebook.com/inthemafia/remote/html_server.php?skip_interstitial=1&xw_controller',
            attack_url=mw_url+'=fight&xw_city=1&xw_action=attack&opponent_id=',
            heal_url=mw_url+'=hospital&xw_action=heal',
            last_url=null,
            tmp="",
            loot='',
            target="",
            bodyguard=false,
            attacks=0,
            wins=0,
            xp_gained=0,
            xp,
            money,
            cur_health=0,
            max_health=0,
            retries=0,
            xpnow=0,
            xpnext=0,
            xpneed=0,
            mwtools_div=$('mwtools'),
            running_html =
                '<style type="text/css">'+
                    '.messages img{margin:0 3px}'+
                    '#pl{display:none}'+
                '</style>'+
                '<table class="messages">'+
                    '<tr>'+
                        '<td><a href="http://vern.com/mwtools/">Vern\'s MW Tools</a></td>'+
                        '<td class="title">'+version+'</td>'+
                        '<td style="text-align:right">'+
                            '<a href="#" id="pa"><img src="http://vern.com/mwtools/pa.gif" title="Pause" width="14" height="14"></a>'+
                            '<a href="#" id="pl"><img src="http://vern.com/mwtools/pl.gif" title="Play" width="14" height="14"></a>'+
                            '<a href="#" id="cl"><img src="http://vern.com/mwtools/cl.gif" title="Close" width="14" height="14"></a>'+
                            '<form name="mwtform">'+
                                '<input type="hidden" name="go" id="go" value="1">'+
                            '</form>'+
                        '</td>'+
                    '</tr>'+
                    '<tr>'+
                        '<td width="20%">Attacks:</td>'+
                        '<td id="attacks"></td>'+
                    '</tr>'+
                    '<tr>'+
                        '<td>Exp Gained:</td>'+
                        '<td id="xp_gained"></td>'+
                    '</tr>'+
                    '<tr>'+
                        '<td>Target:</td>'+
                        '<td id="target" colspan="2"></td>'+
                    '</tr>'+
                    '<tr>'+
                        '<td>Status:</td>'+
                        '<td id="status" colspan="2"></td>'+
                    '</tr>'+
                    '<tr>'+
                        '<td valign="top">Log:</td>'+
                        '<td id="log" colspan="2"></td>'+
                    '</tr>'+
                '</table>';
        if (!mwtools_div) {
            mwtools_div=document.createElement("div");
            mwtools_div.setAttribute('id','mwtools');
            mwtools_div.innerHTML='<table class="messages"></table>';
            content.insertBefore(mwtools_div,content.firstChild);
        }
        // Fix mafia count, just in case it line-wrapped
        mafia_size.innerHTML='<nobr>'+mafia_size.innerHTML.replace(/&nbsp;/g,'')+'</nobr>';
        // get who we're attacking
        if (m=/Your [mM]afia of \d+ fought against (.*?) in (New York|Cuba) with/.exec(content.innerHTML)) {
            target = m[1];
        }
        try {
            if (m=/user=(\d+).+>(.+)<\/a>/.exec(document.getElementsByClassName('fightres_name')[1].innerHTML)) {
                attack_url += m[1];
                target = m[2];
            }
        } catch(err) {
            if (a=/user=(\d+)/.exec($(app+'_content_row').innerHTML))
                attack_url+=a[1];
        }
        if (/As a Top Mafia Bodyguard/.test(content.innerHTML))
            bodyguard=true;

        mwtools_div.innerHTML=running_html;

        function msg(s) {
            $('status').innerHTML=s;
        }
        function log(s) {
            $('target').innerHTML=target+(bodyguard?' (<img src="http://mwfb.static.zynga.com/mwfb/graphics/icon-defense.gif" width="13" height="13"> a Top Mafia Bodyguard)':'');
            $('attacks').innerHTML=attacks+(attacks==0?'':' <span class="more_in">('+(wins/attacks*100).toFixed(1)+"% won)</span>");
            $('xp_gained').innerHTML=xp_gained+(attacks==0?'':' <span class="more_in">('+(xp_gained/attacks).toFixed(2)+" avg)</span>");
            l=$('log');
            l.innerHTML=s+'<br />'+l.innerHTML;
        }
        $("cl").onclick=function(e) { /* close */
            if (xmlHTTP)
                delete xmlHTTP['onreadystatechange'];
            $(app+"_content_row").removeChild($("mwtools"));
            return false;
        }
        $("pa").onclick=function(e) { /* pause */
            document.mwtform.go.value = 0;
            $("pa").style.display = 'none';
            $("pl").style.display = 'inline';
            return false;
        }
        $("pl").style.display = 'none';
        $("pl").onclick=function(e) { /* play */
            document.mwtform.go.value = 1;
            $("pl").style.display = 'none';
            $("pa").style.display = 'inline';
            msg('Resuming: '+resume_msg);
            request(last_url);
            return false;
        }

        if (/=$/.test(attack_url)) {
            msg('You need to be on an Attack results screen to run this bookmarklet.');
            return;
        }

        function get_xmlHTTP() {
            if(window.XMLHttpRequest)
                return new XMLHttpRequest();
            if(window.ActiveXObject)
                return new ActiveXObject('Microsoft.XMLHTTP');
            return null;
        }
        function request(url) {
            if (document.mwtform.go.value == 1) {
                xmlHTTP.onreadystatechange=state_change;
                xmlHTTP.open('GET',url,true);
                xmlHTTP.send(null);
            } else {
                resume_msg=$('status').innerHTML;
                msg('Paused');
            }
            last_url=url;
        }
        function retry(s) {
            if(retries>9) {
                msg(s+'; not retrying any more.');
            } else {
                setTimeout(function(){
                    retries++;
                    msg(s+'; retry #'+retries+'...');
                    request(last_url);
                },3000);
            }
        }
        function state_change() {
            if(xmlHTTP.readyState==4) {
                if(xmlHTTP.status==200) {
                    s=""; m=[];
                    s=xmlHTTP.responseText;
                    delete xmlHTTP['onreadystatechange'];
                    // Stats updates
                    if(m=/app10979261223_user_cash[^>]*>([^<]*)</m.exec(s)) {
                        uc=$(app+'_user_cash_nyc');
                        if(uc) uc.innerHTML=m[1];
                        uc=$(app+'_user_cash_cuba');
                        if(uc) uc.innerHTML=m[1];
                    }
                    if(m=/app10979261223_user_health[^>]*>([^<]*)</.exec(s)) {
                        cur_health = m[1];
                        $(app+'_user_health').innerHTML=cur_health;
                    }
                    if(m=/app10979261223_user_max_health[^>]*>([^<]*)</.exec(s)) {
                        max_health = m[1];
                        $(app+'_user_max_health').innerHTML=max_health;
                    }
                    if(m=/app10979261223_user_energy[^>]*>([^<]*)</m.exec(s))
                        $(app+'_user_energy').innerHTML=m[1] ;
                    if(m=/app10979261223_user_stamina[^>]*>([^<]*)</m.exec(s))
                        $(app+'_user_stamina').innerHTML=m[1];
                    if(m=/app10979261223_user_experience[^>]*>([^<]*)</m.exec(s)) {
                        xpnow=m[1];
                        $(app+'_user_experience').innerHTML=xpnow;
                    }
                    if(m=/app10979261223_exp_for_next_level[^>]*>([^<]*)</m.exec(s)) {
                        xpnext=m[1];
                        $(app+'_exp_for_next_level').innerHTML=xpnext;
                        xpneed=parseInt(xpnext) - parseInt(xpnow);
                        document.getElementsByClassName('stat_title')[5].innerHTML='Exp (Need: '+xpneed+')';
                    }
                    if(m=/<div[^>]*app10979261223_level_bar[^>]* width:\s*([0-9%]*)/.exec(s))
                        $(app+'_level_bar').style.width=m[1];
                    // this usually won't happen...
                    if (/You cannot fight a member of your own family/.test(s)){
                        msg('You cannot fight your own family!');
                        log('Quitting attack spree.');
                        return;
                    }
                    // Old fight results screen style
                    if (m=/Your [mM]afia of \d+ fought against (.*?) in (New York|Cuba) with/.exec(s)) {
                        target = m[1];
                        attacks++;
                        loot='';
                        alive='';
                        if(m=/Attack Again/.test(s))
                            alive='<img src="http://mwfb.static.zynga.com/mwfb/graphics/icon-attack.gif" width="13" height="13" title="there was an Attack Again button"> ';
                        if (/As a Top Mafia Bodyguard/.test(s))
                            bodyguard=true;
                        if(/found .*? while fighting/.test(s)) {
                            loot=' and found ';
                            s.match(/found .*? while fighting/g).each(function(i) {
                                loot += i.match(/found (.*?) while/)[1].replace('{ITEM}','')+', ';
                            });
                            loot=loot.slice(0,loot.length-2);
                        }
                        if(/You took out/.test(s))
                            log('Killed the opponent.');
                        if(e=/You gained (.*?) and (.*?) experience points/.exec(s)) {
                            wins++;
                            money=parseInt(e[1].replace(/[^0-9]/g,''));
                            xp_gained+=parseInt(e[2].replace(/[^0-9]/g,''));
                            log(alive+'Won fight and gained '+(money>0?e[1]+ ' and ':'')+e[2]+' xp'+loot+'.');
                        }
                        if(e=/<strong>LOST<.strong> the fight along with (.*?), taking/.exec(s)) {
                            money=parseInt(e[1].replace(/[^0-9]/g,''));
                            log(alive+'Lost the fight'+(money>0?' and '+e[1]:'')+'.');
                        }
                        if (cur_health < 30) {
                            msg('Getting low on health, visiting the doctor.');
                            request(heal_url+tmp);
                        } else {
                            msg('Attacking again...');
                            request(attack_url+tmp);
                        }
                    } else if(/You will be able to fight again/.test(s)) {
                        msg('Need healing, heading to the doctor.');
                        request(heal_url+tmp);
                    } else if(/The doctor healed/.test(s)) {
                        msg('The doctor did good, resuming attack.');
                        request(attack_url+tmp);
                    } else if(/You are already at full health/.test(s)) {
                        msg('Already healed, resuming attack.');
                        request(attack_url+tmp);
                    } else if(/You need more stamina to fight/.test(s)) {
                        if (cur_health != max_health) {
                            msg('Done fighting, visiting the doctor.');
                            request(heal_url+tmp);
                        } else {
                            msg('Done fighting, out of stamina.');
                        }
                    } else if(/You cannot heal so fast/.test(s)) {
                        msg('Cannot heal so fast, pausing.');
                        setTimeout(function() {
                            msg('Need healing, visiting hospital.');
                            request(heal_url+tmp);
                        },20000);
                    // New graphical fight results screen
                    } else if (/<div class="fight_results">/.test(s)) {
                        attacks++;
                        loot='';
                        alive='';
                        money='';
                        xp='';
                        // get target (it's the last fightres_name)
                        s.match(/div class="fightres_name">.*?<\/a>/g).each(function(i) {
                            target = /"fightres_name">(.*?<\/a>)/.exec(i)[1];
                        });
                        // attack again button check
                        if (/Attack Again/.test(s))
                            alive='<img src="http://mwfb.static.zynga.com/mwfb/graphics/icon-attack.gif" width="13" height="13" title="there was an Attack Again button"> ';
                        // top mafia bodyguard check
                        if (/As a Top Mafia Bodyguard/.test(s))  // unsure
                            bodyguard=true;
                        // loot check
                        if (/found .*? while fighting/.test(s)) {
                            loot=' and found ';
                            s.match(/found .*? while fighting/g).each(function(i) {
                                loot += i.match(/found (.*?) while/)[1].replace('{ITEM}','')+', ';
                            });
                            loot=loot.slice(0,loot.length-2);
                        }
                        // kill check
                        if (/You took out/.test(s))
                            log('Killed the opponent.');
                        // cash check
                        if (e=/"fightres_cash sexy_cash (good|bad)">[-+]([^<]*)</.exec(s)) {
                            money = parseInt(e[2].replace(/[^0-9]/g,''));
                            if (money > 0 || e[1] == "good") {
                                money = '<span class="'+e[1]+'">'+e[2]+'</span>';
                            } else {
                                money = '';
                            }
                        }
                        // xp check
                        if (e=/([-+])(\d+)\s+Experience/.exec(s)) {
                            if (e[2] > 0) {
                                if (e[1] == "+") {
                                    xp = ' and <span class="good">'+e[2]+' xp</span>';
                                    xp_gained += parseInt(e[2]);
                                } else {
                                    xp = ' and <span class="bad">'+e[2]+' xp</span>';
                                    xp_gained -= parseInt(e[2]);
                                }
                            }
                        }
                        // need win/loss check
                        if (/fightres_title good/.test(s)) {
                            wins++;
                            log(alive+'Won fight and gained '+money+xp+loot+'.');
                        } else if (/fightres_title bad/.test(s)) {
                            log(alive+'Lost the fight'+(money?' and '+money:'')+xp+loot+'.');
                        } else {
                            log(alive+'Won/Lost? the fight'+(money?' and '+money:'')+xp+loot+'.');
                        }
                        // need healing?
                        if (cur_health < 30) {
                            msg('Getting low on health, visiting the doctor.');
                            request(heal_url+tmp);
                        } else {
                            msg('Attacking again...');
                            request(attack_url+tmp);
                        }
                    } else if (/Error while loading page/.test(s)) {
                        msg('Mafia Wars is having problems, pausing...');
                        setTimeout(function(){
                            request(last_url);
                        },20000);
                        return;
                    /*} else if (m=/class[^>]*message_body[^>]*>(.*)/.exec(s)) {
                        m[1]=m[1].replace('&','&amp;').replace('<','&lt;').replace('>','&gt');
                        log('Unknown response: '+m[1]);
                        retry('Unknown response');
                        return; */
                    } else if ((tmp == "") && (m=/attack.*?(tmp=[0-9a-f]*)/.exec(s))) {
                        tmp="&"+m[1];
                        msg('Retrieved new tmp key, continuing attack...');
                        request(attack_url+tmp);
                    } else {
                        retry('Unknown response (<a href="'+last_url+'">url</a>)');
                        return;
                    }
                    retries=0;
                } else {
                    retry('Problem retrieving XML data');
                    return;
                }
            }
        }
        xmlHTTP=get_xmlHTTP();
        if(!xmlHTTP) {
            alert('Your browser does not support XMLHTTP.');
            return;
        }
        if($(app+'_user_health').innerHTML<30) {
            msg('Need to heal before we start.');
            request(heal_url+tmp);
        } else {
            request(attack_url+tmp);
            msg('Starting the attack-spree...');
        }
    }
)()
// vim: set sw=4 ts=4 et ai:
