//
// @require autohub.js
//

YAHOO.namespace( 'AutoHub.Login' );

YAHOO.AutoHub.Login = function( )
{
  var E = YAHOO.util.Event ;
  var $ = YAHOO.util.Dom.get ;
  var Widget = null ;

  function _ClickLogin    ( e, o ) { try { o.clickLogin( e ); } finally {} }

  function LoginWidget( x )
  {
    this.sLoginLinkClass     =  x.login_link_class ;
    this.sServerUri          =  x.server_uri ;
    this.sRedirectUri        =  x.redirect_uri ? x.redirect_uri : '/' ;
    this.aIgnoreFelts        =  [] ;

    this.sUsernameParam      =  x.param_username ;
    this.sPasswordParam      =  x.param_password ;
    this.sRememberUserParam  =  x.param_remember_user ;
    this.sRememberPassParam  =  x.param_remember_pass ;

    this.aelLoginLinks       =  [];

    E.onDOMReady((function(o) { return function()
                  {
                    // Get all links on the page. Process each.
                    o.aelLoginLinks = YAHOO.AutoHub.Util.getElementsByClass( 'loginLink', 'a' );
                    for( var i=0; i<o.aelLoginLinks.length; i++ )
                    {
                      // Convert this to a yahoo element
                      o.aelLoginLinks[i] = new YAHOO.util.Element( o.aelLoginLinks[i].id );
                      // Assign click handler to use LoginWidget
                      o.aelLoginLinks[i].on( 'click', _ClickLogin, o );
                    }
                  }})(this));
  }

  // Assign new redirect uri. returns old.
  LoginWidget.prototype.RedirectUri = function( sUri )
  {
    var sOldUri = this.sRedirectUri ;
    this.sRedirectUri = sUri ;
    return sOldUri ;
  }

  /**
   * Called when a user successfully logs in using a valid user+pass
   * You should redirect to wherever you want him to go.
   */
  LoginWidget.prototype.loginSuccess = function( hData )
  {
    // Update authentication state info with new login data
    YAHOO.AutoHub.Data.nUserId    =  hData['nUserId'];
    YAHOO.AutoHub.Data.sUriState  =  hData['sUriState'];

    // Add login state info to the link the user tried to click
    var sUri = YAHOO.AutoHub.Util.UriWithState( this.sRedirectUri );

    // Redirect the user to the link they tried to go to
    YAHOO.AutoHub.Log( "Redirect to "+sUri, false );
    document.location.href = sUri ;
  }

  /**
   * Called when there is an invalid username or password.
   */
  LoginWidget.prototype.loginError = function( )
  {
    YAHOO.AutoHub.Log( "Invalid username or password", false );
    reportLoginError( "Invalid username or password" );  // in Design/autohub.js
  }

  /**
   * Called when there is an internal server error.
   * Do not show sPrivateErrMsg to users!
   */
  LoginWidget.prototype.serverQueryError = function( sPrivateErrMsg )
  {
    YAHOO.AutoHub.Log( "There was an error when querying the server: "+sPrivateErrMsg, false );
    reportLoginError( "Internal server error, please try again" );  // in Design/autohub.js
  }

  LoginWidget.prototype.getEventTarget = function( e )
  {
    for( var eTarget = YAHOO.util.Event.getTarget( e ); eTarget.tagName != 'BODY' ; eTarget = eTarget.parentNode )
    {
      if( eTarget.tagName == 'A' )
        return eTarget;
    }
    return null;
  }

  // event handler when user clicks one of the login links
  LoginWidget.prototype.clickLogin = function( e )
  {
    YAHOO.AutoHub.Log( "Click login!", false );

    var eTarget = this.getEventTarget( e );
    YAHOO.AutoHub.Log("target="+eTarget+", id="+eTarget.id+", tag="+eTarget.tagName, false);
    YAHOO.AutoHub.Log( "Login redirect = ["+eTarget.href+"], title=["+eTarget.title+"]", false );

    // Get the href from the link that was clicked, that is our target
    this.RedirectUri( eTarget.href );
    // use designer's showLogin method to display the form
    showLogin( eTarget.title ? eTarget.title : '', eTarget.href.indexOf('/join/') >=0 ? 'join' : 'login' );  // from Design/autohub.js

    // prevent the browser from following the link href the user clicked,
    // similar to returning false in non-yui event handlers.
    E.stopEvent( e );
  }

  // Should we ignore this form element (by name)?
  LoginWidget.prototype.isIgnoredFelt = function( sName )
  {
    for( var i=0; i<this.aIgnoreFelts.length; i++ )
      if( this.aIgnoreFelts[i] == sName )
        return 1 ;

    return 0 ;
  }
  /*
  LoginWidget.prototype.getForm( oElem )
  {
    for( var aux = oElem; aux.tagName != 'BODY' ; aux = aux.parentNode )
    {
      if( aux.tagName == 'FORM' )
        return aux;
    }
  }*/

  // Event handler when the user tries to submit the login form
  LoginWidget.prototype.clickSubmit = function( oBtn )
  {
    YAHOO.AutoHub.Log( "Login form Submit", false );

    // the event is on the submit button onClick so get the parent form
    for( var aux = oBtn; aux.tagName != 'BODY' ; aux = aux.parentNode )
    {
      if( aux.tagName == 'FORM' )
        oForm = aux;
    }
    
    if (oForm == null)
    {
      YAHOO.AuotHub.Log("Parent form hot found", false);
      this.loginError( );
      return false ;
    }

    var nLength = oForm.length;
    var aElts = oForm.elements;
    var aVars = [];
    var sUser = '' ;
    var sPass = '' ;

    for( var i=0; i<nLength; i++ )
    {
      if( aElts[i].name == this.sUsernameParam )
      {
        aVars[aVars.length] = [ aElts[i].name, aElts[i].value ];
        sUser = aElts[i].value ;
      }

      else if( aElts[i].name == this.sPasswordParam )
      {
        aVars[aVars.length] = [ aElts[i].name, aElts[i].value ];
        sPass = aElts[i].value ;
      }

      else if( aElts[i].name == this.sRememberUserParam || aElts[i].name == this.sRememberPassParam )
      {
        if( aElts[i].checked )
          aVars[aVars.length] = [ aElts[i].name, aElts[i].value ];
      }

      else if( this.isIgnoredFelt( aElts[i].name ) )
        continue ;

      else
        aVars[aVars.length] = [ aElts[i].name, aElts[i].value ];
    }

    var sArgs = '' ;
    for( var i=0; i<aVars.length; i++ )
      sArgs += (sArgs?'&':'') + escape(aVars[i][0]) + '=' + escape(aVars[i][1]); 

    // If they didn't give a username/password, don't submit the form
    if( sUser == '' || sPass == '' )
    {
      YAHOO.AutoHub.Log("Empty username and password", false);
      this.loginError( );
      return false ;
    }

    YAHOO.AutoHub.Log( "@todo Implement an hourglass type 'i am working' thing", false );
    YAHOO.AutoHub.Log( "Login form post args: "+sArgs, false );
    this.queryServer( sArgs );

    return false ;
  }

  // Query the server with the form information
  LoginWidget.prototype.queryServer = function( sArgs )
  {
    var sUri   =  YAHOO.AutoHub.Util.UriWithState( this.sServerUri );

    var hCB    = {
      cache  : false,  // adds "rnd=timestamp" to the URI to prevent caching
      timeout: 5000,   // 5 secs timeout
      success: this.queryCB,
      failure: this.queryCB,
      argument: [this]
    };

    YAHOO.AutoHub.Log( "Submit server query: "+sUri, false );
    YAHOO.util.Connect.asyncRequest( 'POST', sUri, hCB, sArgs );
  }

  // Handle server response
  LoginWidget.prototype.queryCB = function( oResponse )
  {
    var oLoginWidget = oResponse.argument[0] ;
    var sMsg  =  "Query Results: Server says: "
              + oResponse.status + " " + YAHOO.AutoHub.Util.XhtmlEncode( oResponse.statusText );

    if( oResponse.responseText )
      sMsg += "\n" + YAHOO.AutoHub.Util.XhtmlEncode( oResponse.responseText );
    else
      sMsg += " <em>(empty responseText)</em>" ;

    YAHOO.AutoHub.Log( sMsg, true ); // xhtml safe log message

    if( oResponse.status != 200 )
    {
      oLoginWidget.serverQueryError( "Invalid status: "+oResponse.status );
      return false ;
    }

    var sData = oResponse.responseText.replace( /^OK\s+/i, '' ) ;
    if( sData == oResponse.responseText )
    {
      oLoginWidget.serverQueryError( "Malformatted response (no OK, sData=["+sData+"])" );
      return false ;
    }

    sData = sData.replace( /\s*\n.*$/, '' );  // take only the first line, remove all else
    YAHOO.AutoHub.Log( "sData = ["+sData+"]", false );

    var hData = YAHOO.AutoHub.Util.ParseQueryArgs( sData );
    YAHOO.AutoHub.Log( "nUserId = ["+hData['nUserId']+"]", false );
    if( hData['nUserId'] > 0 )
    {
      oLoginWidget.loginSuccess( hData );
      return false ;
    }

    oLoginWidget.loginError( );
    return false ;
  }

  return {
    Init: function(x) { Widget = new LoginWidget( x ); },
    Submit: function(oForm) { return Widget.clickSubmit(oForm); },
    RedirectUri: function(sUri) { return Widget.RedirectUri( sUri ); }
  };

}();
