/* Scribendi.StateManager, version 1.1
 * (c) 2008 Terence Johnson / Scribendi Inc.
 * Based on UI.State (c) 2008 Prototype UI
 * License: MIT - see http://www.prototype-ui.com
 */
if(!window.Scribendi) {Scribendi = {};}

Scribendi.StateManager = (function(browser) {
  var watch, change, changed, fragment;
  
  function getFragment() {
    return top.location.hash.substr(1);
  }
  
  function fragmentChanged(newFragment) {
    document.fire('state:changed', newFragment.toQueryParams() );
    fragment = newFragment;
  }
  document.observe('dom:loaded', function() {
    var initialFragment = getFragment();
    if (initialFragment) { fragmentChanged(initialFragment); }
    
    if (!!document.body.onhashchange) {

      document.body.onhashchange = fragmentChanged(getFragment());

      change = function(newFragment) {
        top.location.hash = newFragment || '_';
      };

    } else {

      if (browser.IE && browser.appVersion < 8) {
        var iframe = new Element('iframe', { style: 'display: none', src: 'javascript:;' });
        document.body.appendChild(iframe);
  
        var contentWindow = iframe.contentWindow;

        var writeFragmentToIFrame = function(fragment) {
          var doc = contentWindow.document;
          doc.open();
          doc.write(fragment || '');
          doc.close();
        };

        var readFragmentFromIFrame = function() {
          return contentWindow.document.body.innerText;
        };

        writeFragmentToIFrame(fragment);
      
        watch = function() {
          var newFragment = readFragmentFromIFrame();
          if (newFragment != fragment) {
            top.location.hash = newFragment || '_';
            fragmentChanged(newFragment);
          }
        };
      
        change = function(newFragment) {
          if (newFragment != fragment) { writeFragmentToIFrame(newFragment); }
        };

      } else {    
        // watching history.length is only useful for WebKit
        var counter = history.length, fragments = [ ];
      
        watch = function() {
          var newFragment = getFragment(), newCounter = history.length;
          if (newFragment != fragment) { fragmentChanged(newFragment); }
          else if (newCounter != counter) {
            fragmentChanged(fragments[newCounter - 1]);
            fragment = newFragment;
          }
          counter = newCounter;
        };
            
        change = function(newFragment) {
          top.location.hash = newFragment || '_';
          if (browser.WebKit) { fragments[history.length] = newFragment; }
        };
      }
      
      setInterval(function() { if (changed) { watch(); } }, 200);
    }
  });
  
  return {
    change: function(ev) {
      var state = $H(getFragment().toQueryParams());
      state.update(ev.memo);
      change(state.toQueryString());
      changed = true;
    },
   
    watch: function() {
      watch();
    }
  };
})(Prototype.Browser);

if (Prototype.Browser.Opera && parseFloat(navigator.appVersion) < 9.5 ) {
  document.write('<img src="javascript:location.href=\'javascript:Scribendi.StateManager.watch();\';" style="position:absolute; top:-1000px" />');
}

document.observe('state:change', Scribendi.StateManager.change);