// Copyright 2009 John Heminghous
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// Loader - loads pages into the div with ID "contentID" using AJAX
//
function Loader(contentID, defaultLocation)
{
  // Check parameters
  if (!contentID || !defaultLocation)
  {
    return;
  }
  
  //
  // Private variables
  //
  var _pageLoad = false;
  var _currentLocation = "";
  var _initialized = false;
  var _preloadFunctions = new Array();
  var _loadFunctions = new Array();
  
  // Initialize object
  initialize();
  
  //
  // Public functions
  //
  this.initialized = function() { return _initialized; }
  
  // Passed in notifiable objects should inherit from the Notifiable interface
  this.addPreloadNotify = function(preloadFunction)
  {
    _preloadFunctions.push(preloadFunction);
  }
  
  this.addLoadNotify = function(loadFunction)
  {
    _loadFunctions.push(loadFunction);
  }
  
  //
  // Private functions
  //
  function initialize()
  {
    if (!createRequest())
    {
      return;
    }
    
    if (alterLinks())
    {
      _initialized = true;
      initializeLocation();
      
      // Poll to see if address bar location has changed every 200 ms
      setTimeout(checkLocationChange, 200);
    }
  }
  
  function alterLinks(elementID)
  {
    // Use document element if no ID was passed in
    var element = null;
    if (!elementID)
    {
      element = document;
    }
    else
    {
      element = document.getElementById(elementID);
      if (!element)
      {
        return false;
      }
    }
    
    // Override default link behavior
    var links = document.getElementsByTagName("a");
    for (var i = 0; i < links.length; ++i)
    {
      var location = links[i].href;
      if (location.indexOf("dispatcher.php?target=") > -1)
      {
        location = 
          location.substr(location.indexOf("dispatcher.php?target=")+22);
        links[i].href = "#"+location;
      }
    }
    
    return true;
  }

  function pageLocation()
  {
    return window.location.href;
  }

  function baseLocation()
  {
    var location = pageLocation();
    return location.split("#")[0];
  }

  function targetLocation()
  {
    var location = pageLocation();
    if (location.indexOf("#") > -1)
    {
      var locationParts = location.split("#");
      return locationParts[locationParts.length-1];
    }
    else
    {
      return defaultLocation;
    }
  }

  function makeLocation(target)
  {
    return baseLocation()+"#"+target;
  }

  function checkLocationChange()
  {
    if (targetLocation() != _currentLocation)
    {
      _currentLocation = targetLocation();
      loaderInvoke(_currentLocation);
      window.location = makeLocation(targetLocation());
    }
    
    setTimeout(checkLocationChange, 200);
  }
  
  function initializeLocation()
  {
    if (targetLocation() == defaultLocation)
    {
      _currentLocation = targetLocation();
      window.location = makeLocation(targetLocation());
    }
  }

  function loaderInvoke(location)
  {
    // Execute preload events
    for (var i = 0; i < _preloadFunctions.length; ++i)
    {
      _preloadFunctions[i](contentID);
    }
    
    // Send AJAX page request
    if (!ajaxTextGet(
      "dispatcher.php?target="+location+"&partial", loaderCallback))
    {
      content.innerHTML = "Error: AJAX request failed";
      
      // Execute load events
      for (var i = 0; i < _notifiables.length; ++i)
      {
        if (_notifiables[i].notifyLoad)
        {
          _notifiables[i].notifyLoad(contentID, false);
        }
      }
    }
    
    return false;
  }

  function loaderCallback(contents)
  {
    // Load returned content into the DOM
    var contentContainer = document.getElementById(contentID);
    if (!contentContainer)
    {
      return;
    }
    contentContainer.innerHTML = contents;
    
    // Alter newly loaded links
    alterLinks(contentID);
    
    // Execute load events
    for (var i = 0; i < _loadFunctions.length; ++i)
    {
      _loadFunctions[i](contentID, true);
    }
  }
}
