// based on the google toolbar v3/4 checksum algo
// from http://pagerank.gamesaga.net/
// adapted from the PHP script.

page_rank = function() {
    this.int32Unit = 4294967296;  // 2^32
}

page_rank.prototype = {
    form_google_url: function(url) {
        var checksum = this.check_hash(this.hash_url(url));

        gurl = 'http://www.google.com/search?client=navclient-auto&features=Rank:';
        gurl += '&q=info:' + urlencode(url) + '&ch=' + checksum;

        return gurl;
    },

    str_to_num: function(url, check, magic) {
        var len = url.length;

        for(var i = 0; i < len; i++) {
            check *= magic;

            if (check >= this.int32Unit) {
                check = check - this.int32Unit * Math.round(Math.floor(check / this.int32Unit));

                //if the check less than -2^31
                check = (check < -2147483648) ? (check + this.int32Unit) : check;
            }

            check += url.charCodeAt(i);
        }
        return check;
    },

    // creates a hash given the url.
    hash_url: function(url) {
        var check1 = this.str_to_num(url, 0x1505, 0x21);
        var check2 = this.str_to_num(url, 0, 0x1003F);

        check1 >>>= 2;

        check1 = ((check1 >>> 4) & 0x3FFFFC0 ) | (check1 & 0x3F);
        check1 = ((check1 >>> 4) & 0x3FFC00 ) | (check1 & 0x3FF);
        check1 = ((check1 >>> 4) & 0x3C000 ) | (check1 & 0x3FFF);

        var t1 = ((((check1 & 0x3C0) << 4) | (check1 & 0x3C)) <<2 ) | (check2 & 0xF0F );
        //var t2 = ((((check1 & 0xFFFFC000) << 4) | (check1 & 0x3C00)) << 0xA) | (check2 & 0xF0F0000);

        var t2 = this.add4b((((check1 & 0xFFFFC000) << 4) | (check1 & 0x3C00)) << 0xA);
        t2 = this.add4b(t2 | (check2 & 0xF0F0000));

        return this.add4b(t1 | t2);

    },

    //genearate a checksum for the hash string
    check_hash: function(hash_num) {
        var check_byte = 0;
        var flag = 0;

        var hash_str = hash_num + '' ;
        var len = hash_str.length;
        var x = 0;

        for (var i = len - 1; i >= 0; i--) {
            x = parseInt(hash_str[i]);
            if(1 == (flag % 2)) {
                x += x;
                x = Math.round(Math.floor(x / 10)) + (x % 10);
            }
            check_byte += x;
            flag++;
        }

        check_byte %= 10;
        if (0 != check_byte) {
            check_byte = 10 - check_byte;
            if (1 == (flag % 2) ) {
                if (1 == (check_byte % 2)) {
                    check_byte += 9;
                }
                check_byte >>>= 1;
            }
        }

        return '7' + check_byte + hash_str;
    },

    // left shifting in Js might result in negative numbers since only 31 bits are used.
    add4b : function(v) {
        return (v < 0) ? (v + this.int32Unit) : v;
    },

    do_nothing: function() {}
}
