// ==SiteScript==
// @siteName    zoome
// @siteUrl     http://www.zoome.jp/
// @author      DarkKnight
// @authorUrl   http://darkknightlabs.com/
// @scriptUrl   http://darkknightlabs.com/site-script/
// @description 
// @date        2008/09/07
// @version     0.6
// ==/SiteScript==


function CravingSiteScript() {
    this._initialize();
}


CravingSiteScript.prototype = {
    _xhr: null,
    
    _initialize: function() {},
    
    _getXmlHttpRequest: function() {
        if ( this._xhr != null ) {
            return this._xhr;
        }
        
        var xhr = null;
        var these = [
              function() { return new XMLHttpRequest(); }
            , function() { return new ActiveXObject( "Msxml2.XMLHTTP" ); }
            , function() { return new ActiveXObject( "Microsoft.XMLHTTP" ); }
            , function() { return new ActiveXObject( "Msxml2.XMLHTTP.4.0" ); }
        ];
        
        for ( var i = 0, length = these.length; i < length; i++ ) {
            var func = these[ i ];
            try {
                xhr = func();
                break;
            }
            catch( e ) {}
        }
        this._xhr = xhr;
        
        return this._xhr;
    },
    
    _load: function( url, data, method ) {
        var req = this._getXmlHttpRequest();
        
        var mtd = ( method == null ) ? "GET" : "POST";
        
        req.open( mtd, url, false );
        
        if ( mtd == "POST" ) {
            req.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
        }
        
        req.send( data );
        
        return req.responseText;
    },
    
    getResponseText: function( url, data, method ) {
        return this._load( url, data, method );
    },
    
    getResponseJSON: function( url, data, method ) {
        var text = this._load( url, data, method );
        
        return eval( "("+text+")" );
    },
    
    /// Math
    random: function( limit ) {
        return Math.floor( Math.random() * limit );
    },
    
    /// String
    decodeHtml: function( str ) {
        return str.replace( /&(quot|#34);/ig,    "\"" )
                  .replace( /&(amp|#38);/ig,     "&"  )
                  .replace( /&(apos|#39);/ig,    "'"  )
                  .replace( /&(lt|#60);/ig,      "<"  )
                  .replace( /&(gt|#62);/ig,      ">"  )
                  .replace( /&(nbsp|#160);/ig,   " "  )
                  .replace( /&(frasl|#8260);/ig, "/"  );
    }
}


function CryptRC4() {
    this._initialize();
}


CryptRC4.prototype = {
    _sbox: null,
    _key: null,
    
    _initialize: function() {
        _sbox = new Array( 255 );
        _key = [ 55, 50, 102, 50, 55, 100, 97, 101, 51, 100, 53, 99, 101, 57, 99, 101, 98, 56, 48, 51, 101, 97, 97, 100, 53, 48, 99, 51, 100, 54, 53, 55 ];
    },
    
    decrypt: function ( text ) {
        var str = this._hexToChars( text );
        var result = this._calculate( str, _key );
        
        return this._charsToStr( result );
    },
    
    _hexToChars: function ( hex ) {
        var result = new Array();
        var i = ( hex.substr( 0, 2 ) == '0x' ) ? 2 : 0;
        
        for ( ;i < hex.length; i += 2 ) {
            result.push( parseInt( hex.substr( i, 2 ), 16 ) );
        }
        
        return result;
    },
    
    _charsToStr: function ( chars ) {
        var result = new String( '' );
        
        for ( var i = 0; i < chars.length; i++ ) {
            result += String.fromCharCode( chars[ i ] );
        }
        
        return result;
    },
    
    _setKey: function ( key ) {
        var keys = new Array( 255 );
        var len = key.length;
        
        for ( var i = 0; i < 256; i++ ) {
            keys[ i ] = key[ i % len ];
            _sbox[ i ] = i;
        }
        
        for ( var i = j = 0; i <= 255; i++ ) {
            j = ( j + _sbox[ i ] + keys[ i ] ) % 256;
            
            var tmp = _sbox[ i ];
            _sbox[ i ] = _sbox[ j ];
            _sbox[ j ] = tmp;
        }
    },
            
    _calculate: function ( str, key ) {
        this._setKey( key );
        var result = new Array();
        
        for ( var i = j = k = 0; i < str.length; i++ ) {
            j = ( j + 1 ) % 256;
            k = ( k + _sbox[ j ] ) % 256;
            
            var tmp = _sbox[ j ];
            _sbox[ j ] = _sbox[ k ];
            _sbox[ k ] = tmp;
            
            tmp = ( _sbox[ j ] + _sbox[ k ] ) % 256;
            var s = _sbox[ tmp ];
            var t = str[ i ] ^ s;
            
            result.push( t );
        }
        
        return result;
    }
}


function isSiteUrl( url ) {
    if ( url.match( /^http:\/\/(circle\.)?zoome\.jp\/.*\/.+\/\d+/ ) ) {
        return true;
    }
}


function getVideoDetail( url ) {
    var craving = new CravingSiteScript();
    var text = craving.getResponseText( url );
    
    if ( text == null ) {
        return null;
    }
    
    text.match( /id="zoome_funktion"\s+value="(.*)"/ );
    var funktion = RegExp.$1;
    var circle = funktion == 'circle' ? true : false;
    
    var xmlUrl;
    var crypt = new CryptRC4();
    
    if ( circle ) {
        xmlUrl = url.replace( /media/, 'swf_media' );
        xmlUrl += "?filename=zpmcmedn&dummy=" + craving.random( 1000 );
    }
    else {
        text.match( /<title>(.*)<\/title>/ );
        title = RegExp.$1.replace( /zoome.*: /, "" );
        title = String( title ).replace( / - .*/, "" );
        title = craving.decodeHtml( title );
        
        text.match( /id="mypage_diary_xml"\s+value="(.*)"/ );
        xmlUrl = crypt.decrypt( RegExp.$1 );
    }
    
    text = craving.getResponseText( xmlUrl );
    
    if ( text == null ) {
        return null;
    }
    
    if ( circle ) {
        text.match( /<title>(.*?)<\/title>/ );
        var title = decodeURIComponent( RegExp.$1.replace( /\+/g, '%20' ) );
    }
    
    var urlMatch;
    if ( circle ) {
        urlMatch = text.match( /<url_movie>(.*)<\/url_movie>/ );
    }
    else {
        urlMatch = text.match( /<videoURL>(.*)<\/videoURL>/ );
    }
    
    var realUrl;
    
    if ( urlMatch == null ) {
        text.match( /<yourURL>(.*)<\/yourURL>/ );
        var baseUrl = decodeURIComponent( RegExp.$1 );
        
        text.match( /<uid>(.*)<\/uid>/ );
        var uid = RegExp.$1.split( '_' );
        var diary_id = parseInt( uid[ 1 ] );
        
        xmlUrl = baseUrl + 'data_movie?format=xml'
        xmlUrl += '&diary_id=' + diary_id;
        xmlUrl += '&dummy=' + craving.random( 1000 );
        xmlUrl += '&filename=zpmmdian';
        
        text = craving.getResponseText( xmlUrl );
        
        text.match( /<mp401 encode_stat="(.*?)".*><srcs><src>(.*?)<\/src>/ );
        
        if ( 'encoded' == RegExp.$1 ) {
            realUrl = crypt.decrypt( RegExp.$2 );
        }
        else {
            text.match( /<flv01 encode_stat=".*?".*><srcs><src>(.*?)<\/src>/ );
            realUrl = crypt.decrypt( RegExp.$1 );
        }
    }
    else {
        var urlMovie = RegExp.$1;
        realUrl = crypt.decrypt( urlMovie );
        realUrl = realUrl.replace( /,.*/, "" );
        
        text.match( /<h264_encode_stat>(.*)<\/h264_encode_stat>/ );
        
        if ( 'encoded' == RegExp.$1  ) {
            realUrl = realUrl.slice( 0, -3 ) + 'mp4';
        }
    }
    
    return { videoTitle0: title, videoUrl0: realUrl };
}
