OpenLayers.Layer.Geoportail = OpenLayers.Class(OpenLayers.Layer.WMS, {
  token: null,
  ttl: 240,		/* ttl of token in seconds */
  lastToken: null,	/* timestamp of last token in milli-seconds */
  key: null,
  timeOut: null,	/* timer id used for token update */
  script: null,		/* script DOM element used for loading the new token */
  loadingToken: false,	/* whether we requested a new token */

  initialize: function( name, key, options )
    {
    var newArguments = [];

/*    params = OpenLayers.Util.upperCaseObject( params );
    OpenLayers.Util.applyDefaults(
                       params,
                       OpenLayers.Util.upperCaseObject( { exceptions: "text/xml" } )
                       );*/


    Proj4js.defs["IGNF:GEOPORTALFXX"]="+title=Geoportail - France metropolitaine +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=46.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs";

    this.attribution = '<a href="http://www.geoportail.fr/"><img border="0" src="http://api.ign.fr/js/1.0beta3/theme/geoportal/img/logo_gp.gif"/></a>&nbsp;&nbsp;&nbsp;' +
                       '<a href="http://www.ign.fr/"><img border="0" src="http://www.geoportail.fr/legendes/logo_ign.gif"/></a>';

    this.key = key;
    if ( typeof( Geoportal ) == "undefined" ) { Geoportal = { }; }
    if ( ! Geoportal.GeoRMHandler ) { Geoportal.GeoRMHandler = { }; }
    if ( ! Geoportal.GeoRMHandler[ "U" + key ] ) { Geoportal.GeoRMHandler[ "U" + key ] = { }; }
    if ( ! Geoportal.GeoRMHandler[ "U" + key ].callback ) { Geoportal.GeoRMHandler[ "U" + key ].callback = OpenLayers.Function.bind( this.tokenCallback, this ); }

    if ( ! options ) { options = {}; }
    OpenLayers.Util.applyDefaults( options,
      {
        units: "m",
        maxExtent: new OpenLayers.Bounds( -1149409.2127717289,3784862.6869713017,1992309.3021376631,6456530.466009867 ),
        resolutions: [ 2048,1024,512,256,128,64,32,16,8,4,2 ], /* [39135.75,19567.875,9783.9375,4891.96875,2445.984375,2048,1024,512,256,128,64,32,16,8,4,2,1,0.5,0.25,0.125,0.0625],*/
        projection: new OpenLayers.Projection( "IGNF:GEOPORTALFXX" ) /*projection: new OpenLayers.Projection( "EPSG:27582" )*/ /*projection: "IGNF:MILLER"*/
      } );

    if ( options.ttl ) { this.ttl = options.ttl; }
    newArguments.push( name, "http://wxs.ign.fr:80/geoportail/wmsc", { "LAYERS": "GEOGRAPHICALGRIDSYSTEMS.MAPS", "EXCEPTIONS": "text/xml", "FORMAT": "image/jpeg", "TILED": "true" }, options );

    OpenLayers.Layer.WMS.prototype.initialize.apply(this, newArguments);
    },

  destroy: function( )
    {

    if ( this.timeOut )
      {
      window.clearTimeout( this.timeOut );
      this.timeOut = null;
      }

    OpenLayers.Layer.WMS.prototype.destroy.apply( this, arguments );
    },

/* clone */

  calculateGridLayout: function(bounds, extent, resolution)
    {
    return OpenLayers.Layer.WMS.prototype.calculateGridLayout.apply( this, [ bounds, new OpenLayers.Bounds( 0, 0, 0, 0 ), resolution ] );
    },


  moveTo: function( bounds, zoomChanged, dragging )
    {
    if ( ! this.getToken( ) ) { return; }
    OpenLayers.Layer.WMS.prototype.moveTo.apply( this, arguments );
    },

  getToken: function( )
    {
    var time = ( new Date( ) ).getTime( );
    if ( this.token && this.lastToken && ( this.lastToken + 1000 * this.ttl / 2 > time ) )	/* ask for new token after half the ttl */
      { return this.token; }

/*alert( "token: "+this.token+"\nlasttoken: "+this.lastToken+"\ntime: "+time );*/

    if ( ! this.loadingToken )
      {
      this.script       = document.createElement( "script" );
      this.script.src   = "http://jeton-api.ign.fr/getToken?key=" + this.key + "&output=json&callback=Geoportal.GeoRMHandler.U" + this.key + ".callback";
      this.script.defer = true;
      document.body.appendChild( this.script );

      this.timerId = window.setTimeout( OpenLayers.Function.bind( this.setToken, this ), this.ttl * 1000 / 5 );
      this.loadingToken = true;
      }

    if ( this.token && this.lastToken && ( this.lastToken + 1000 * this.ttl > time ) ) { return this.token; }

    return false;
    },

  tokenCallback: function( token )
    {
    if ( token && token.gppkey )
      {
      this.token = token.gppkey;
      this.params.GPPKEY = this.token;
      this.loadingToken = false;
      window.clearTimeout( this.timerId );
      this.timerId = null;
      document.body.removeChild( this.script );
      this.script = null;
      this.lastToken = ( new Date( ) ).getTime( );

      this.map.setCenter( this.map.center, this.map.zoom, false, true );
      }
    },

  setToken: function( )
    {
    if ( this.loadingToken )
      {
      window.clearTimeout( this.timerId );
      this.timerId = null;
      document.body.removeChild( this.script );
      this.script = null;
      this.loadingToken = false;
      this.getToken( );
      }
    },

  CLASS_NAME: "OpenLayers.Layer.Geoportail"
} );

