// ==UserScript==
// @name           Reader Bar
// @namespace      net.moeffju.utilities
// @description    Aid the user in finding the previous reading position after scrolling.
// @include        *
//
// @version        0.21
// @author         Matthias Bauer <http://moeffju.net/>
// @homepage       http://moeffju.net/projects/userscripts/readerbar/
// @license        Creative Commons BY-SA 2.5
// ==/UserScript==

//
// Reader Bar is (c) 2007 Matthias Bauer <http://moeffju.net/>
// http://moeffju.net/projects/userscripts/readerbar/
//
// Licensed under the Creative Commons Attribution-ShareAlike license, version 2.5
// <http://creativecommons.org/licenses/by-sa/2.5/>
// 
// You are free:
// 
//     * to Share -- to copy, distribute, display, and perform the work
//     * to Remix -- to make derivative works
// 
// Under the following conditions:
// 
//     * Attribution. You must attribute the work in the manner specified by the author or licensor.
//     * Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.
// 
//     * For any reuse or distribution, you must make clear to others the license terms of this work.
//     * Any of these conditions can be waived if you get permission from the copyright holder.
// 

//
// Settings begin here. Adjust these to your liking.
//

var MARKER_COLOR = 'red';       // any valid CSS color
var MARKER_THICKNESS = '4px';   // any valid CSS measurement
var MARKER_OPACITY = 0.5;       // a floating point number between 0 and 0.999999999 (1 brings out the bad in Firefox)
var MARKER_DURATION = 3000;     // how long to show the marker, in milliseconds

var MIN_SCROLL_DIST = 150;      // minimum scroll distance to trigger (you should not need to change this)

//
// Settings end here. Touch stuff below at your own risk. Pants are strictly optional.
//

var scrollpos;
var previouspos;
var viewport;
var hidetimer;

var mdx;
var mdy;

var marker;

var getViewportSize = function() {
  if (typeof window.innerWidth != 'undefined') {
    return [window.innerWidth, window.innerHeight];
  }
  else if (typeof document.documentElement != 'undefined'
        && typeof document.documentElement.clientWidth != 'undefined'
        && document.documentElement.clientWidth != 0) {
    return [document.documentElement.clientWidth, document.documentElement.clientHeight];
  }
  else {
    return [document.getElementsByTagName('body')[0].clientWidth, document.getElementsByTagName('body')[0].clientHeight   ];
  }
  
  return [0,0];
}

var getScrollPos = function() {
  // standards-compliant browsers
  if (typeof window.pageYOffset != 'undefined') {
    return [window.pageXOffset, window.pageYOffset];
  }
  // IE 5, IE 6 quirks mode
  else if (typeof document.documentElement.scrollTop != 'undefined'
        && document.documentElement.scrollTop > 0) {
    return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
  }
  // IE 6
  else if (typeof document.body.scrollTop != 'undefined') {
    return [document.body.scrollLeft, document.body.scrollTop];
  }

  // complete failure
  return [0,0];
}

var createMarker = function() {
  marker = document.createElement('div');
  initMarker();
  document.getElementsByTagName('body')[0].appendChild(marker);
}

var initMarker = function() {
  marker.style.opacity = MARKER_OPACITY;
  marker.style.border = ['none', MARKER_COLOR, MARKER_THICKNESS].join(' ');
  marker.style.position = 'absolute';
  marker.style.zIndex = '4000';
  hideMarker();
}

var showMarker = function() {
  marker.style.display = 'block';
}

var hideMarker = function() {
  marker.style.display = 'none';
}

var setMarker = function(x1, y1, x2, y2, dx, dy) {
  marker.style.left = [x1, 'px'].join('');
  marker.style.top = [y1, 'px'].join('');
  marker.style.width = [x2 - x1, 'px'].join('');
  marker.style.height = [y2 - y1, 'px'].join('');
  
  // scrolled horizontally
  if (dx < 0) { marker.style.borderLeftStyle = 'solid'; }
  if (dx > 0) { marker.style.borderRightStyle = 'solid'; }
  // scrolled vertically
  if (dy < 0) { marker.style.borderTopStyle = 'solid'; }
  if (dy > 0) { marker.style.borderBottomStyle = 'solid'; }
  
  // ONLY horizontally
  if (dy == 0 && dx != 0) {}
  // ONLY vertically
  if (dx == 0 && dy != 0) { marker.style.width = '100%'; }
}

var update = function() {
  var diff = [scrollpos[0] - previouspos[0], scrollpos[1] - previouspos[1]];
  
  if (Math.abs(diff[0]) > mdx || Math.abs(diff[1]) > mdy) {
    initMarker(); // also hides
    // mark previous viewport
    setMarker(
      previouspos[0], previouspos[1], previouspos[0] + viewport[0], previouspos[1] + viewport[1],
      diff[0], diff[1]);
    showMarker();
    
    if (hidetimer) { window.clearTimeout(hidetimer); }
    hidetimer = window.setTimeout(hideMarker, MARKER_DURATION);
  }
}

var onScroll = function() { previouspos = scrollpos; scrollpos = getScrollPos(); update(); }
var onViewportSizeChange = function() { viewport = getViewportSize(); update(); }

/* init */
createMarker();

viewport = getViewportSize();
scrollpos = getScrollPos();
previouspos = scrollpos;

mdx = mdy = MIN_SCROLL_DIST;
// if the viewport is tinier than MIN_SCROLL_DIST
if (MIN_SCROLL_DIST < viewport[1] / 2) {
  mdx = viewport[0] / 2;
  mdy = viewport[1] / 2;
}

/* scroll position listeners */
window.addEventListener('scroll', onScroll, true);
window.setInterval(onScroll, 250);

/* viewport size change listener */
window.setInterval(onViewportSizeChange, 500);

