// GENERAL INFORMATION
//
// We use "virtual" classnames: no CSS exists for them, they are for Javascript
// to find them easily. Those classnames are:
//
//  hasToolTip, hasToolTipNormal
//    the element has a title attribute that should serve as YUI tooltip. Two
//    types: hasToolTip is for long texts and therefore has a width-limit set
//
//  showLoggedOut, showLoggedIn
//    the element should be made visible/invisible (using display:block/none)
//    on a page if the user is logged in/out, respectively
//
// We expect a global variable LETEXA_LOGGED_IN set by PHP on the server side
// already set when we get to this file. This indicates if the page was generated
// with the user logged in or not.

//separate namespaces - and global shortcuts, does that fit? No, but I'm lazy...
YAHOO.namespace("letexa");
var L = YAHOO.letexa;
var DOM = YAHOO.util.Dom;
var EVENT = YAHOO.util.Event;

//This object provides functions that can be used by the code on the individual pages of the site
L.globals = function () {
  //private variables and methods
  var oMenuBar;
  var tt1,tt2;  //tooltips
  var linkBtns = [];  //buttons from links
  var fullNameCookie = null;
  //all elements marked with "virtual" classnames for logged-in/out states
  var loggedOutArr = [];
  var loggedInArr = [];

  return {
    //public variables

    //public methods, access via L.globals.function()

    //event bubbling: onmouseover/out highlighting and click handling, used in pages that list links to courses in a UL
    fnMouseEvents: function (e,o) {
      var t = EVENT.getTarget(e, 1);
      //go up in the DOM tree until the parent LI with class="highlight" is found
      while (!DOM.hasClass(t,"highlight")) {
        //the entire LI, parent of the A, should be highlighted
        if (t.nodeName.toUpperCase() == "LI") {
          if (o.clicked) {
            //make click on the parent LI area same as click on the (first) child A
            location.href = t.getElementsByTagName("a")[0].href;
          } else {
            if (o.over) {
              DOM.addClass(t,"over");
              //make the URL show up in the status bar also when the mouse is not over the A element
              window.status = t.getElementsByTagName("a")[0].href;
            } else {
              DOM.removeClass(t,"over");
              window.status = "";
            }
          }
          break;
        } else {
          t = t.parentNode;
        }
      }
    },

    //some cookie handling functions not in the YUI
    createCookie: function (name,value,days) {
      var expires="";
      if (days) {
        var date=new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        expires="; expires="+date.toGMTString();
      }
      document.cookie=name+"="+value+expires+"; path=/";
    },

    readCookie: function (name) {
      var nameEQ=name+"=";
      var ca=document.cookie.split(";");
      for(var i=0;i<ca.length;i++) {
        var c=ca[i];
        while (c.charAt(0)===" ") {
          c=c.substring(1,c.length);
        }
        if (c.indexOf(nameEQ)===0) {
          return c.substring(nameEQ.length,c.length);
        }
      }
      return null;
    },

    eraseCookie: function (name) {
      this.createCookie(name,"",-1);
    },

    //set the page up for logged-in state
    loggedIn: function () {
      //hide all elements that should not be displayed in this state
      for (var i = 0; i < loggedOutArr.length; i++) {
        loggedOutArr[i].style.display = "none";
      }
      //show all elements that should be displayed in this state
      for (var j = 0; j < loggedInArr.length; j++) {
        loggedInArr[j].style.display = "block";
      }
      //see if this cookie is set (it is if login was in this browser session and if the AJAX login was used)
      fullNameCookie = L.globals.readCookie("fullname");
      //Special case: page generated in logged-out state
      if (fullNameCookie !== null) {
        DOM.get("loggedIN_name").innerHTML = fullNameCookie;
      }
      //Call page-specific JS code, if it exists
      if (L.local && L.local.loggedIn) {
        L.local.loggedIn();
      }
    },

    //set the page up for logged-out state
    loggedOut: function () {
      //hide all elements that should not be displayed in this state
      for (var i = 0; i < loggedInArr.length; i++) {
        loggedInArr[i].style.display = "none";
      }
      //show all elements that should be displayed in this state
      for (var j = 0; j < loggedOutArr.length; j++) {
        loggedOutArr[j].style.display = "block";
      }
      //Call page-specific JS code, if it exists
      if (L.local && L.local.loggedOut) {
        L.local.loggedOut();
      }
    },

    init: function () {
      loggedOutArr = DOM.getElementsByClassName("showLoggedOut");
      loggedInArr = DOM.getElementsByClassName("showLoggedIn");

      oMenuBar = new YAHOO.widget.MenuBar("menu", { autosubmenudisplay: true, hidedelay: 600 });
      oMenuBar.render();

      //see if this cookie is set (it is if login was in this browser session and if the AJAX login was used)
      fullNameCookie = L.globals.readCookie("fullname");

      //Make it possible to have YUI-style tooltips simply by adding a title attribute and
      //one of two class-names to HTML elements. Two class-names: the fixed-width one is for long texts
      tt1 = new YAHOO.widget.Tooltip("tt1",{context:DOM.getElementsByClassName("hasTooltip"),width:"32em",autodismissdelay:50000});
      tt2 = new YAHOO.widget.Tooltip("tt2",{context:DOM.getElementsByClassName("hasTooltipNormal"),autodismissdelay:50000});

      //automatically create buttons from all link-button anywhere on the page
      var lnks = DOM.getElementsByClassName("yui-link-button");
      for (i = 0; i < lnks.length; i++) {
        linkBtns[linkBtns.length] = new YAHOO.widget.Button(lnks[i].id);
      }

      //Execute code that sets up the page for logged-in/out state.
      //Because we use AJAX we cannot rely on the server-side (PHP) to generate those
      //differences reliably - if a user logs in using AJAX the original PHP-generated HTML was
      //for the logged-out state, for example, and the same happens when a user presses BACK in the
      //browser after having logged in - we go back to a page generated in logged-out state originally

      //Determine login state and act upon it. The cookie, if set, overwrites the setting provided
      //by PHP on the server, because the server could not know about the AJAX login.
      //See /footer.inc for the location where LETEXA_LOGGED_IN is set by PHP.
      if (LETEXA_LOGGED_IN || fullNameCookie!==null) {
        L.globals.loggedIn();
      } else {
        L.globals.loggedOut();
      }
    }
  };
}();

//This object provides and controls the AJAX Login-dialog and makes it available on every
//page. All that page has to have is include a link element with id="loginLnk".
L.loginDlg = function () {
  //private variables and methods
  var loginWin;
  var loginWinFT;
  var kl_ESC, kl_RETURN;

  //HTML for the contents of the login window - we generate this so that it's not in the regular HTML page
  var loginWinHTML = '    <div class="hd">Login</div>';
  loginWinHTML = loginWinHTML.concat('    <div class="bd">',
'      <form id="loginForm" action="/fnc/login.php" method="post">',
'<pre>',
'<label for="user"><span class="underline">L</span>ogin-ID:  </label><input type="text" id="user" name="user" size="25" maxlength="25" accesskey="l" />\n\n',
'<label for="password"><span class="underline">P</span>assword:  </label><input type="password" id="password" name="password" size="25" maxlength="25" accesskey="p" />\n',
'</pre>',
'        <p id="loginFailure" style="display:none; margin: 1.4em 0 0 0; color:#e00;text-align:center;">Login failed.</p>',
'        <p style="margin: 1.6em 0 0 0;" class="small">Not yet registered? <a href="/forum/index.php?&amp;action=register">Click here</a>.</p>',
'        <p style="margin: 0.5em 0 0 0;" class="small">Forgot your password? <a href="/forum/index.php?action=reminder">Click here</a>.</p>',
'      </form>',
'      <p id="loginInProgress" style="display:none;text-align:center;" class="waiting">Attempting to log you in...</p>',
'    </div>');

  //intercept clicks on "Login" link, which otherwise points to login page for non-AJAX browsers
  var interceptLnk = function (e) {
    EVENT.preventDefault(e);
    loginWin.show();
  };

  //handlers for the form and the Cancel-button
  var handleValidation = function() {
    var data = this.getData();
    if (data.user === "" || data.password === "") {
      alert("Please enter your login ID and password.");
      return false;
    } else {
      DOM.get("loginInProgress").style.display = "block";
      DOM.get("loginFailure").style.display = "none";
      DOM.get("loginForm").style.display = "none";
      loginWinFT.style.display = "none";
      return true;
    }
  };

  var handleSubmit = function () {
    this.submit();
  };

  var handleCancel = function () {
    DOM.get("loginInProgress").style.display = "none";
    DOM.get("loginFailure").style.display = "none";
    DOM.get("loginForm").style.display = "block";
    loginWinFT.style.display = "block";
    loginWin.cancel();
  };

  //handlers for the AJAX submittal of the login form data
  var handleSuccess = function(o) {
    DOM.get("loginInProgress").style.display = "none";
    DOM.get("loginFailure").style.display = "none";
    DOM.get("loginForm").style.display = "block";
    loginWinFT.style.display = "block";
    var r = null;
    try {
      r = YAHOO.lang.JSON.parse(o.responseText);
    }
    catch (e) {
      //do nothing, handled below
    }
    if (r!==null && r[0] && r[0].realName && r[0].realName!=="") {
      //This is to store the name for those cases where PHP could not create new
      //HTML to reflect the new logged-in state. It is set ONLY here, and not via PHP,
      //because it is only useful when a user logs in using the async. Javascript method
      //Of course, it has to be UNset in the PHP logout script
      L.globals.createCookie("fullname",r[0].realName,0);
      loginWin.hide();
      L.globals.loggedIn();
    } else {
      //failure after all
      handleFailure();
    }
  };

  var handleFailure = function(o) {
    DOM.get("loginInProgress").style.display = "none";
    DOM.get("loginFailure").style.display = "block";
    DOM.get("loginForm").style.display = "block";
    loginWinFT.style.display = "block";
  };

  return {
    //public variables

    //public methods
    init: function () {
      //generate the Window
      var w = document.createElement("div");
      w.id = "loginWin";
      w.innerHTML = loginWinHTML;
      document.body.appendChild(w);

      //define the login window properties
      loginWin = new YAHOO.widget.Dialog("loginWin",
        { width: "28em",
          fixedcenter : true,
          visible: false,
          modal: true,
          hideaftersubmit: false,
          constraintoviewport: true,
          postmethod: "async",
          buttons : [ { text:"Login", handler:handleSubmit, isDefault:true },
                      { text:"Cancel", handler:handleCancel } ]
        });

      //prepare the DOM for the dialog
      loginWin.render();

      //the footer of the dialog, which contains the buttons
      loginWinFT = DOM.getElementsByClassName("ft","div","loginWin")[0];

      //validate login window form data before doing anything
      loginWin.validate = handleValidation;

      //callbacks for AJAX submittal of login dialog data
      loginWin.callback = { success:handleSuccess, failure:handleFailure, timeout: 15000 };

      //listen for ESC and RETURN keys (for cancel and submit key shortcuts)
      kl_ESC = new YAHOO.util.KeyListener(document, { keys:27 },
                { fn: loginWin.cancel,
                  scope: loginWin,
                  correctScope: true } );
      kl_RETURN = new YAHOO.util.KeyListener(document, { keys:13 },
                { fn: loginWin.submit,
                  scope: loginWin,
                  correctScope: true } );

      //make sure status messages are hidden and key listeners on (and off, respectively)
      loginWin.beforeShowEvent.subscribe(function () {
          DOM.get("loginInProgress").style.display = "none";
          DOM.get("loginFailure").style.display = "none";
          DOM.get("loginForm").style.display = "block";
          loginWinFT.style.display = "block";
          kl_ESC.enable();
          kl_RETURN.enable();
      });
      loginWin.hideEvent.subscribe(function () {
          kl_ESC.disable();
          kl_RETURN.disable();
       });

      //everything has been set up - now we can intercept the login link on the page
      EVENT.addListener("loginLnk", "click", interceptLnk);
    }
  };
}();

//This object provides and controls the AJAX Logout-dialog and makes it available on every
//page. All that page has to have is include a link element with id="logoutLnk".
L.logoutDlg = function () {
  //private variables and methods
  var logoutWin;
  var kl_ESC, kl_RETURN;
  var request;
  var callback = {
    success: function(o) {
      var r = null;
      try {
        r = YAHOO.lang.JSON.parse(o.responseText);
      }
      catch (e) {
        //do nothing, handled below
      }
      if (r!==null && r[0] && r[0].success) {
        logoutWin.hide();
        L.globals.loggedOut();
      } else {
        //failure after all
        this.failure();
      }
    },
    failure: function(o) {
      logoutWin.cfg.setProperty("text","Failed to logout, for some unknown reason...");
      logoutWin.cfg.setProperty("buttons", [
        { text:"Try again", handler:handleYes, isDefault:true },
        { text:"Cancel",  handler:handleNo }
      ]);
    },
    timeout: 15000
  };

  //intercept clicks on "Logout" link, which otherwise points to logout page for non-AJAX browsers
  var interceptLnk = function (e) {
    EVENT.preventDefault(e);
    logoutWin.show();
  };

  //handle the two dialog buttons
  var handleYes = function () {
    logoutWin.cfg.setProperty("text",'<p class="waiting" style="text-align:center;">Attempting to log you out...</p>');
    logoutWin.cfg.setProperty("buttons", []);
    request = YAHOO.util.Connect.asyncRequest('GET', "/fnc/logout.php", callback);
  };

  var handleNo = function () {
    logoutWin.hide();
  };

  return {
    //public variables

    //public methods
    init: function () {
      //define the logout window properties
      logoutWin = new YAHOO.widget.SimpleDialog("logoutWin",
        { width: "28em",
          fixedcenter : true,
          visible: false,
          modal: true,
          close: true,
          constraintoviewport: true,
          hideaftersubmit: false
        });

      logoutWin.setHeader("Logout");

      //prepare the DOM for the dialog
      logoutWin.render("doc");

      //callbacks for AJAX submittal of logout dialog data
      logoutWin.callback = { success:L.logoutDlg.handleSuccess, failure:L.logoutDlg.handleFailure, timeout: 15000 };

      //listen for ESC and RETURN keys (for cancel and submit key shortcuts)
      kl_ESC = new YAHOO.util.KeyListener(document, { keys:27 },
                { fn: logoutWin.cancel,
                  scope: logoutWin,
                  correctScope: true } );
      kl_RETURN = new YAHOO.util.KeyListener(document, { keys:13 },
                { fn: handleYes,
                  scope: logoutWin,
                  correctScope: true } );

      //make sure status messages are hidden and key listeners on (and off, respectively)
      logoutWin.beforeShowEvent.subscribe(function () {
          logoutWin.cfg.setProperty("text","Do you want to logout now?");
          logoutWin.cfg.setProperty("buttons", [
            { text:"Yes", handler:handleYes, isDefault:true },
            { text:"No",  handler:handleNo }
          ]);
          kl_ESC.enable();
          kl_RETURN.enable();
      });
      logoutWin.hideEvent.subscribe(function () {
          kl_ESC.disable();
          kl_RETURN.disable();
      });

      //everything has been set up - now we can intercept the logout link on the page
      EVENT.addListener("logoutLnk", "click", interceptLnk);
    }
  };
}();

EVENT.onDOMReady(function () {
  L.globals.init();
  L.loginDlg.init();
  L.logoutDlg.init();

  //the local object contains code local to the page, especially code that sets certain page
  //elements depending on logged-in state - see below (L.local.loggedIn / loggedOut functions)
  if (L.local && L.local.init) {
    L.local.init();
  }
});

//try to prevent hijacking of our pages in frames
if (top != self) {
  top.location = self.location;
}
