/* Changes:
    1.07    Fix for new fight results screen
            Added exp average and win percentage
    1.06    Fix reporting of loot on Safari
    1.05    Format change on won fights
            Added target and if they are a Top Mafia Bodyguard
            Added money won/lost (if not zero)
    1.04    New tmp variable
            Added pause button
            Added new version check
    1.03    Added specific error message and pause for the "Error while
            loading page" to differentiate it from other unknown responses.
*/
javascript:(//)
    function(){
        var version='AttackCuba 1.07',
            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&ajax=1&xw_controller',
            attack_url=mw_url+'=fight&xw_city=2&xw_action=attack&opponent_id=',
            heal_url=mw_url+'=hospital&xw_action=heal',
            ny_url=mw_url+'=travel&xw_action=travel&destination=1&xw_city=1&from=index',
            cuba_url=mw_url+'=travel&xw_action=travel&destination=2&xw_city=2&from=index',
            last_url=null,
            atmp="",
            ttmp="",
            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('Health low, heading to New York.');
                            request(ny_url+ttmp);
                        } else {
                            msg('Attacking again...');
                            request(attack_url+atmp);
                        }
                    // 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) {
                                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]);
                            }
                        }
                        // 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('Health low, heading to New York.');
                            request(ny_url+ttmp);
                        } else {
                            msg('Attacking again...');
                            request(attack_url+atmp);
                        }
                    } else if(/You will be able to fight again/.test(s)) {
                        msg('Need healing, heading to New York.');
                        request(ny_url+ttmp);
                    } else if(/The doctor healed/.test(s)) {
                        msg('The doctor did good, heading back to Cuba.');
                        request(cuba_url+ttmp);
                    } else if(/You are already at full health/.test(s)) {
                        msg('Already healed, heading back to Cuba.');
                        request(cuba_url+ttmp);
                    } else if(/You need more stamina to fight/.test(s)) {
                        if (cur_health != max_health) {
                            msg('Done fighting, heading to New York.');
                            request(ny_url+ttmp);
                        } 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+atmp);
                        },20000);
                    } else if ((atmp == "") && (m=/attack.*?(tmp=[0-9a-f]*)/.exec(s))) {
                        atmp="&"+m[1];
                        msg('Retrieved new attack tmp key, checking for travel tmp key...');
                        request(cuba_url+ttmp);
                    } else if ((ttmp == "") && (m=/travel.*?(tmp=[0-9a-f]*)/.exec(s))) {
                        ttmp="&"+m[1];
                        msg('Retrieved new travel tmp key.');
                        if($(app+'_user_health').innerHTML<30) {
                            msg('Need healing, heading to New York.');
                            request(ny_url+ttmp);
                        } else {
                            msg('Attacking...');
                            request(attack_url+atmp);
                        }
                    } else if (/button_travel_nyc.*setStyle.*block/.test(s)) {
                        msg('Back in Cuba, resuming attacks.');
                        request(attack_url+atmp);
                    } else if (/button_travel_cuba.*setStyle.*block/.test(s)) {
                        msg('In New York, visiting doctor.');
                        request(heal_url+atmp);
                    } else if (/Error while loading page/.test(s)) {
                        msg('Mafia Wars is having problems, pausing...');
                        setTimeout(function(){
                            request(last_url);
                        },20000);
                        return;
                    } 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;
        }
        msg('Starting the attack-spree...');
        request(attack_url+atmp);
    }
)();
// vim: set sw=4 ts=4 et ai:
