// COPYRIGHT 2008 CITRUS MEDIA GROUP. ALL RIGHTS RESERVED!



//~~~~~~~~~~~~~~~~~~~~~~~~~~//
//        SLIDESHOW         //
//~~~~~~~~~~~~~~~~~~~~~~~~~~//


var SlideShow = new Class({
  Implements: Options,
  options: {
    parent: null,
    selector: null,
    randomStart: true,
    delay: 3700,
    fadeInDelay: 1100,
    fadeOutDelay: 800
  },
  initialize: function(options) {
    this.setOptions(options);
    this.slides = $$('#' + this.options.parent + ' ' + this.options.selector);
    this.setup();
    this.start();
  },
  setup: function() {   	      
    this.tInt = 0;
    this.totalSlides = this.slides.length;
    this.currentSlide = this.options.randomStart ? $randomRange(0, this.totalSlides - 1) : 0;
    var i = this.totalSlides;
    while (i--) {
      if (i != this.currentSlide) {
        this.slides[i].setStyles({
          'z-index': 0,
          'opacity': 0
        });
      } else this.slides[i].setStyle('z-index', 5000);
    }
  },
  start: function() {
    this.totalSlides = this.slides.length;
    this.status = 'playing';
   this.tInt = $clear(this.tInt);
   this.tInt = this.transition.periodical(this.options.delay, this);
  },
  transition: function() {
    if (this.status != 'playing') this.tInt = $clear(this.tInt);   	      
    if ($chk(this.activeSlide)) {
      this.lastSlide = this.activeSlide;
      this.lastSlide.get('tween', { property: 'opacity', duration: this.options.fadeOutDelay, onComplete: function() {
        this.lastSlide.setStyle('z-index', 0);
      }.bind(this)}).start(0);
    }
    this.activeSlide = this.slides[this.currentSlide];   	      
    this.activeSlide.setStyles({
      'z-index': 5000 	        
    }).get('tween', { property: 'opacity', duration: this.options.fadeInDelay }).start(1);
    this.currentSlide++;
    if (this.currentSlide >= this.totalSlides) this.currentSlide = 0;
  }
});



//~~~~~~~~~~~~~~~~~~~~~~~~~~//
//         PREVIEW          //
//~~~~~~~~~~~~~~~~~~~~~~~~~~//


var Preview = {
	preview: '...',
	show: function() {
	 	if (this.preview == '...') this.preview = new Previewer({ src: arguments[0] });
		else this.preview.show(arguments[0]);
	}
};


var Previewer = new Class({
  Implements: Options,
  
  img: null,
  ldr: null,
  size: null,
  winSize: null,
  winScroll: null,
  observeLoad: null,
	observeClick: null,
	observeScroll: null,
	observeResize: null,
	
	options: {
		src: null
	},
  initialize: function(options){
      this.setOptions(options);
      this.observeLoad = this.handleLoad.bindWithEvent(this);
			this.observeClick = this.handleClick.bindWithEvent(this);
			this.observeScroll = this.handleScroll.bindWithEvent(this);
			this.observeResize = this.handleResize.bindWithEvent(this);
			this.ldr = new NetStatus({alignWith: 'mouse'}).start();
    	this.img = this.create();
    	if ($chk(this.options.src)) this.show(this.options.src);
  },
  create: function() {
   return new Element('img', {
  		'id': 'previewImg',
  		'styles': {
	  		'display': 'block',
      	'position': 'absolute',
 	    	'border': '3px solid #333',
      	'cursor': 'pointer'
      },
      'events': {
      	'load': this.observeLoad,
    		'click': this.observeClick
    	}
    }).fade('hide');
 	},
 	show: function(src) {
 	  this.options.src = src ? src : this.options.src;
 	  this.img.fade('hide').setProperty('src', this.options.src + '?cc=' + Math.round(Math.random() * 100));
 	},
 	handleLoad: function() {
   	this.size = this.img.inject(document.body).getSize();
 		this.winSize = window.getSize();
 		this.winScroll = window.getScroll();
 		this.img.setStyles({ 'left': this.winScroll.x + (this.winSize.x * 0.5) - (this.size.x * 0.5) + 'px', 'top': this.winScroll.y + (this.winSize.y * 0.5) - (this.size.y * 0.5) + 'px' }).inject(document.body).fade('in');
 		this.ldr.hide().remove();
   	this.img.addEvent('click', this.observeClick);
   	window.addEvent('scroll', this.observeScroll);
   	window.addEvent('resize', this.observeResize);
 	},
 	handleClick: function() {
 	  this.img.removeEvent(this.observeClick);
 		this.img.fade('out').dispose.delay(1000, this.img);
 	},
 	handleScroll: function() {
 	  this.winScroll = window.getScroll();
 		this.img.setStyles({ 'left': this.winScroll.x + (this.winSize.x * 0.5) - (this.size.x * 0.5) + 'px', 'top': this.winScroll.y + (this.winSize.y * 0.5) - (this.size.y * 0.5) + 'px' });
  },
 	handleResize: function() {
 	  this.winSize = window.getSize();
 		this.img.setStyles({ 'left': this.winScroll.x + (this.winSize.x * 0.5) - (this.size.x * 0.5) + 'px', 'top': this.winScroll.y + (this.winSize.y * 0.5) - (this.size.y * 0.5) + 'px' });
  }
});






//~~~~~~~~~~~~~~~~~~~~~~~~~~//
//      NET STATUS          //
//~~~~~~~~~~~~~~~~~~~~~~~~~~//


var NetStatus = new Class({
  Implements: Options,
  
  div: null,
  pos: 0,
  loops: 0,
  status: 'idle',
  animInt: 0,
  statusInt: 0,
  mouseMove: null,
  winScroll: null,
  
  options: {
      imagePath: '/images/netstatus.png',
      size: 18,
      timeout: 10,
      margin: 7,
      alignWith: null
  },
  initialize: function(options){
      this.setOptions(options);
      this.div = this.create();
      if ($chk(this.options.alignWith)) {
        if (this.options.alignWith == 'mouse') {
          this.mouseMove = this.handleMouseMove.bind(this);
          window.addEvent('mousemove', this.mouseMove);
        } else this.options.alignWith = $type(this.options.alignWith) == 'string' ? $(this.options.alignWith) : this.options.alignWith;
        this.alignWith();
      }
      window.addEvent('resize', this.handleResize.bind(this));
  },
  create: function () {
    return new Element('div', {
      'id': 'netStatus' + Math.random(),
      'styles': {
          'display': 'block',
          'width': this.options.size + 'px',
          'height': this.options.size + 'px',
          'position': 'absolute',
          'background': 'transparent url(' + this.options.imagePath + ') 0 0 no-repeat'
      }
    }).fade('hide').inject(document.body);
  },
  start: function() {
    if (this.status == 'loading') return false;
    this.div.fade('show');
    this.pos = 0;
    this.loops = 0;
  	this.status = 'loading';
    this.animInt = $clear(this.animInt);
    this.animInt = this.anim.periodical(100, this);
    return this;
  },
  error: function(s) {
  	this.status = s ? s : 'error';	
  	this.div.setStyle('backgroundPosition', '0 ' + -(this.options.size * 12) + 'px').fade('show');
  	this.hide.delay(1750, this);
  	return this;
  },
  stop: function(navTo) {
    this.statusInt = $clear(this.statusInt);
  	this.statusInt = this.setStatus.delay(350, this, 'idle');
  	this.remove.delay(450, this);
  	if (navTo) this.setLocation.delay(500, this, navTo);
  	return this;
  },
  hide: function() {
    this.div.fade('out');
    return this;
  },
  remove: function() {
    this.status = 'idle';
    window.removeEvent('mousemove', this.mouseMove);
    this.div = this.div.dispose();
    return this;
  },
  anim: function() {
    if (this.status != 'loading') this.animInt = $clear(this.animInt);
    else {
      this.pos -= this.options.size;
      if (this.pos <= -(this.options.size * 12)) {
        this.pos = 0;
        this.loops++;
        if (this.loops >= this.options.timeout) {
          this.status = 'idle';
          this.error('timeout');
          return false;
        }
      }
      this.div.setStyle('backgroundPosition', '0 ' + this.pos + 'px');
    }
  },  
  alignWith: function(el) {
    if (el) this.options.alignWith = el;
    if (this.options.alignWith == 'mouse') return false;
  	else if ($type(this.options.alignWith) == 'string') this.options.alignWith = $(this.options.alignWith);
  	if (!$chk(this.div) || !$chk(this.options.alignWith)) return false;  	
  	var cords = this.options.alignWith.getCoordinates();
  	this.div.setStyles({left: (cords.left + cords.width + this.options.margin) + 'px', top: (cords.top + (cords.height * 0.5) - (this.options.size * 0.5)) + 'px'});
  	return this;
  },
  setLocation: function (navTo) {
    window.location.href = navTo;
  },
  setStatus: function (status) {
    this.statusInt = $clear(this.statusInt);
    this.status = status;
    return this;
  },
  handleResize: function(evt) {
    if (this.options.alignWith != null) this.alignWith(this.options.alignWith);
  },
  handleMouseMove: function(evt) {
    this.winScroll = window.getScroll();
 		this.div.setStyles({left: this.winScroll.x + (evt.client.x + (this.options.size * 0.5)) + 'px', top: this.winScroll.y + (evt.client.y - this.options.size) + 'px'});
  }
});





//~~~~~~~~~~~~~~~~~~~~~~~~~~//
//        DEBUGGER          //
//~~~~~~~~~~~~~~~~~~~~~~~~~~//


var Debug = {
	console: '...',
	trace: function() {
		if (this.console == '...') this.console = new Console();
		this.console.trace(arguments);
	},
	clear: function() {
    if ($chk(this.console)) this.console.clear();	
	}
};


var Console = new Class({
  Implements: Options,

  div: null,
    
  options: {
    height: 600
  },
  initialize: function(options){
    this.setOptions(options);
    if (!$('debugConsole')) this.div = this.create();
    else this.div = $('debugConsole');
    this.div.addEvent('click', function(evt) {
      if (evt.shift) this.clear();
    }.bind(this));
  },
  create: function () {
    return new Element('div', {
      'id': 'debugConsole',
      'styles': {
        'display': 'block',
        'width': '420px',
        'height': this.options.height + 'px',
        'position': 'absolute',
        'right': 0,
        'top': 0,
        'overflow': 'auto',
        'border-top': '3px solid #999',
        'background-color': '#fff',
        'font': '13px Courier'
      }
    }).inject(document.body);
  },
  trace: function () {
  	if (!arguments || arguments.length == 0) return false;
  	else if ($type(arguments[0]) == 'arguments') arguments = arguments[0];
  	var str = '';
  	for (var i = 0, l = arguments.length; i < l; i++){
      str += (arguments[i] + ' ');
    }
    this.div.appendText(str);
   	new Element('br').inject(this.div);
    return str;
  },
  traceObject: function () {
    if (typeof(arguments[0]) == 'object') {
    	for (var i in arguments[0]) {
    		this.div.appendText(i + ' : ' + arguments[0][i]);
    		this.div.innerHTML += '<br/>';
    	}
   	}
    this.div.innerHTML += '<br/>';
  },
  clear: function () {
    this.div.innerHTML = '';
  }
});



//~~~~~~~~~~~~~~~~~~~~~~~~~~//
//     util Functions       //
//~~~~~~~~~~~~~~~~~~~~~~~~~~//


function $random(i) {
  return Math.floor(i * (Math.random() % 1));
}
function $randomRange(i, j) {
  return i + $random(j - i + 1);
}

