/*****************/
/*     SETUP     */
/*****************/

var rURL = 'http://805ink.com/';

var Debug;


if (Debug === true) {
	Event.observe(window, 'load', function(evt) {
		evt.stop();
		Debug = new Console({height: 300, right: 10, bottom: 10}).trace('CREATED!');
	});
}



/*****************/
/*  Form Action  */
/*****************/

var FormAction = Class.create({
  transport: {},
  options: null,
  fields: [],
  div: null,
  title: null,
  form: null,
  ldr: null,
  msg: null,
  valid: false,
  initialize: function(div, form, trans, options) {
    if (this.div) return false;
    this.div = $(div);
    this.title = this.div.firstDescendant();
    this.form = !options.cancelFocus ? $(form).focusFirstElement() : $(form);
    this.transport = trans;
    this.options = Object.extend({
		  	fields: null,
		  	aim: null,
		  	btn: null,
		  	btnCancel: null,
		  	validate: true,
		  	dateFormat: 'dddd, MMMM dd, yyyy h:mm:ss tt'
		}, options || {});
    this.valid = this.options.validate ? new Validation(this.form, {onSubmit: false, useTitles: true}) : true;
    if (this.options.btnCancel) Event.observe(this.options.btnCancel, 'click', this.handleClick.bind(this));
    if (!this.options.aim) Event.observe(this.form, 'submit', this.handleSubmit.bindAsEventListener(this));
    return this.prep();
  },
  prep: function () {
  	var i = this.options.fields.length;
  	while (i--) {
  		//if (this.options.fields[i].type == undefined) this.options.fields[i].type = 'text';
  		
  		this.options.fields[i].type = this.options.fields[i].type ? this.options.fields[i].type : 'text';
  		
  	}
  	return this;
  },
  toggleMsg: function(id) {
    if (!this.div) return this;
    this.msg = $(id);
    if (!this.msg.visible()) {
      var cord = this.div.positionedOffset();
      this.msg.setStyle({
      	left: cord.left + 'px',
      	top: cord.top + 'px',
        width: this.div.getWidth() + 'px',
        height: (this.div.getHeight() + 10) + 'px',
        zIndex: 4000
      });      
      this.enableBtns();
      Effect.BlindDown(this.msg.id, {duration: .7});
    } else {
      Effect.BlindUp(this.msg.id, {duration: .7});
    }
    return this;
  },
  enableBtns: function() {
  	var str = '#' + this.msg.id + ' a.btn';
 		var arr = $$(str);
  	var i = arr.length;
  	while (i--) {
  	  Event.observe(arr[i], 'click', handleClick);
  	}
  	return this;
  },
  hideCurMsg: function() {
    Effect.BlindUp(this.msg.id, {duration: .7});
    return this;
  },
  clearRequired: function(id) {
  	var fld = fld = $('fld_' + id); 
  	if (fld.hasClassName('required')) fld.removeClassName('required');
  	fld.writeAttribute({title: null});
  }, 
  makeRequired: function(id, msg) {
  	var fld = fld = $('fld_' + id); 
  	if (!fld.hasClassName('required')) fld.addClassName('required');
  	if (msg !== undefined) fld.writeAttribute({title: msg});
  },
  setForm: function(title, btn, cfcM) {
    if (title && this.title) this.title.update(title);
    if (btn && this.options.btn) $(this.options.btn).value = btn;
		if (cfcM && this.transport) this.transport.cfcMethod = cfcM;
		this.clearForm().unlockForm();
	 	if (!this.div.visible()) return this.toggleForm();
	 	else return this.scrollTo();
  },
  scrollTo: function() {
  	new Effect.ScrollTo(this.div.id);
  	return this;
 	},
  toggleForm: function(evt, str, cfcM) {
  	if (cfcM) this.transport.cfcMethod = cfcM;
  	if (this.div.visible()) {
  	  Effect.BlindUp(this.div.id, {duration: .7});
  	} else {
  		Effect.BlindDown(this.div.id, {duration: .7, afterFinish: this.scrollTo.bind(this)});
  	}
  	return this;
  },
  fillValues: function(dat) {
  	var fld, i, t, len = dat.DATA[0].length;
  	for (i = 0; i < len; i++) {
  	  val = dat.DATA[0][i] != null ? dat.DATA[0][i] : '';
    	t = this.options.fields[i].type !== undefined ? this.options.fields[i].type : 'text';
  	  switch (t) {
        case 'select':
          fld = $('fld_' + this.options.fields[i].id);	    
          var j = fld.options.length;
          while(j--) if(val == fld.options[j].value) fld.options[j].selected = true;
          break;
        case 'date':
	        fld = $('fld_' + this.options.fields[i].id);       
          fld.value = Date.parse(val) ? Date.parse(val).toString(this.options.dateFormat) : null;
          break;
        case 'checkbox':
        	fld = $('fld_' + this.options.fields[i].id);
        	fld.checked = val == 1 ? true : false;
          break;
        case 'timestamp':
          break;
        default:
       		fld = $('fld_' + this.options.fields[i].id);
		  		fld.value = unescape(val);
      }
 		}
 		if (!this.div.visible()) this.toggleForm();
  },
  makeTransport: function() {
		if (!this.transport.cfc || !this.transport.cfcMethod) return this;
		if (Debug && Debug.trace !== undefined) Debug.trace('TRANS: ' + this.transport.cfc + '.' + this.transport.cfcMethod);
		if (this.transport.params) delete this.transport.params;
		this.transport.params = {};
    this.transport.method = 'post';
    this.transport.alignWith = this.options.btn ? this.options.btn : this.transport.alignWith; 
   	var val, t, i = this.options.fields.length;
    while (i--) {
    	t = this.options.fields[i].type !== undefined ? this.options.fields[i].type : 'text';
      switch (t) {
        case 'date':
          val = Date.parse($F('fld_' + this.options.fields[i].id));
          this.transport.params[this.options.fields[i].id] = val ? val.toString('yyyy-MM-dd HH:mm:ss') : undefined;          
          break;
      	case 'checkbox':
      		this.transport.params[this.options.fields[i].id] = $('fld_' + this.options.fields[i].id).checked ? 1 : 0;
      		break;
        case 'timestamp':
          this.transport.params.date = new Date().toString('yyyy-MM-dd HH:mm:ss');
          break;
        default:
		  		this.transport.params[this.options.fields[i].id] = escape($F('fld_' + this.options.fields[i].id));
      }
    }
    return this;  
  },
  lockForm: function() {
    var i = this.options.fields.length;
    while (i--) {
    	switch (this.options.fields[i].type !== undefined ? this.options.fields[i].type : 'text') {
    		case 'timestamp':
    			break;
    		default:
    			if ($('fld_' + this.options.fields[i].id)) $('fld_' + this.options.fields[i].id).disabled = true;
    	}
    }
    //while (i--) if (this.options.fields[i].type != ('timestamp') && $('fld_' + this.options.fields[i].id)) $('fld_' + this.options.fields[i].id).disabled = true;
    
    return this;
  },
  unlockForm: function() {
    var i = this.options.fields.length;
    while (i--) {
    	switch (this.options.fields[i].type !== undefined ? this.options.fields[i].type : 'text') {
    		case 'timestamp':
    			break;
    		default:
    			if ($('fld_' + this.options.fields[i].id)) $('fld_' + this.options.fields[i].id).disabled = false;
    	}
    }
    return this;
  },
  clearForm: function() {
    var i = this.options.fields.length;
    while (i--) {
    	switch (this.options.fields[i].type !== undefined ? this.options.fields[i].type : 'text') {
    		case 'timestamp':
    			break;
    		case 'checkbox':
    			$('fld_' + this.options.fields[i].id).checked = false;
    			break;
    		default:
    			if ($('fld_' + this.options.fields[i].id)) $('fld_' + this.options.fields[i].id).value = ''
    	}
    }
    return this;
  },
  sendAIM: function () {
		if (typeof(this.valid) == 'object' && !this.valid.validate()) return false;		
		this.transport = new AIM(this.form.id, {show: this.options.aim.show || false, onStart: this.options.aim.onStart, onComplete: this.options.aim.onComplete});	
		return this.transport.submit();
  },
  handleSubmit: function(evt) {
  	evt.stop();
		var b = typeof(this.valid) == 'object' ? this.valid.validate() : this.valid;
		if (b) this.handleValidate(true, this.form);
  },
  handleClick: function(evt) {
  	evt.stop();
  	switch (evt.target.id) {
  	  case this.options.btnCancel:
  	  	if (this.div.visible()) this.toggleForm();
  	  	break;
  	}
  },
  handleValidate: function(result, form) {
    if (!result || !this.transport || this.options.aim) return false;
	  this.makeTransport().lockForm();
	  new DataTransport(this.transport).send();
	  return true;
  }
});




/*****************/
/*   Preview     */
/*****************/

var Preview = Class.create({
	div: null,
	img: null,
	options: {},
	observe: false,
	observeLoad: null,
	observeClick: null,
	initialize: function(options) {
		this.options = Object.extend({
			src: null,
			loader: null
		}, options || {});
		this.observeLoad = this.handleLoad.bindAsEventListener(this);
		this.observeClick = this.handleClick.bindAsEventListener(this);
    return this.create().addListeners();
  },
  create: function() {
  	this.img = new Element('img', {'src': this.options.src}).setStyle({
      border: '3px solid #333'
    });
  	this.div = new Element('div').setStyle({
      display: 'block',
      position: 'fixed'
    });
  	return this;
 	},
 	addListeners: function() {
 		Event.observe(this.img, 'load', this.observeLoad);
 		Event.observe(this.div, 'click', this.observeClick);
 		this.observe = true;
 		return this;
 	},
 	handleLoad: function(evt) {
  	if (this.img) Event.stopObserving(this.img, 'load', this.observeLoad);
  	if (this.options.loader) this.options.loader.remove();
  	document.body.appendChild(this.div.update(this.img));
  	this.div.setStyle({
  		left: (document.viewport.getWidth() * .5) - (this.img.getWidth() * .5) + 'px',
  		top: (document.viewport.getHeight() * .5) - (this.img.getHeight() * .5) + 'px'
  	});
  	return this;
 	},
 	handleClick: function(evt) {
  	return this.exit();
 	},
 	exit: function() {
 		if (this.div) {
	 		if (this.observe) Event.stopObserving(this.div, 'click', this.observeClick);
	 		this.observe = false;
	 		if (this.img)	this.img.remove();
	 		this.div.remove();
	 	}
 		this.img = null;
 		this.div = null; 
  	return null;
 	}
});


/*****************/
/*     Data      */
/*****************/

var DataTransport = Class.create({
	options: null,
	loader: null,
	initialize: function(options) {
    this.options = Object.extend({
			DEBUG: false,
			debug: false,
			callBack: null,
			enctype: 'application/x-www-form-urlencoded',
			method: 'get',
			cfc: null,
			cfcMethod: null,
			params: {
				reqDate: new Date().getTime()
			},
			showLoading: true,
			alignWith: null
		}, options || {});
    return this;
  },
  send: function (params) {   
  	if (this.loader) this.loader.remove();
  	this.loader = null;
  	this.options.params = params !== undefined ? params : this.options.params;
    if (this.options.debug && Debug && Debug.trace !== undefined) Debug.trace('Ajax Request; method: ' + this.options.method + ' cfc: ' + this.options.cfc + ' cfcMethod: ' + this.options.cfcMethod + ' <br/>URL: ' + (rURL + 'cfc/' + this.options.cfc + '.cfc'));
    if (this.options.showLoading) this.loader = this.options.alignWith ? new NetStatus().alignWith(this.options.alignWith).start() : new NetStatus().start();
    new Ajax.Request(rURL + 'cfc/' + this.options.cfc + '.cfc', {
      contentType: this.options.enctype,
      requestHeaders: { Accept: 'application/json; charset=utf-8' },
      method: this.options.method,
      parameters: this.options.params ? {method: this.options.cfcMethod, paramstr: Object.toJSON(this.options.params)} : {method: this.options.cfcMethod},
      onSuccess: this.success.bind(this),
      onFailure: this.fail.bind(this)
    });
    return true;
  },
  success: function(transport) {
    if (this.options.DEBUG && Debug && Debug.trace !== undefined) {
  		Debug.trace('==============================');
  		for (var i in transport) Debug.trace(i + ' : ' + transport[i]);
  		Debug.trace('==============================');
  		for (var i in this.options) Debug.trace(i + ' : ' + this.options[i]);
  		Debug.trace('==============================');
  	}
  	var res = transport.responseJSON ? transport.responseJSON.unfilterJSON() : transport.responseText.evalJSON(true);
    var dat = res.isJSON() ? res.evalJSON(true) : {error:'Not JSON Format'}; 	
  	if (this.loader) this.loader.stop(this.options.navTo ? this.options.navTo : null).remove();
  	if (this.options.callBack) this.options.callBack(dat);
  },
  fail: function(evt){      	
    if (Debug && Debug.trace !== undefined) for (var i in evt) Debug.trace(i + ' : ' + evt[i]);
    if (this.loader) this.loader.error();
  }
});



/*****************/
/*   NetStatus   */
/*****************/

var NetStatus = Class.create({
	options: null,
	pos: 0,
	loops: 0,
	div: null,
	status: 'idle',
	stopAnim: false,
  initialize: function(options) {
    this.options = Object.extend({
  	  timeout: 10,
  	  size: 18,
  	  src: '/images/netstatus.png'
  	}, options || { });
  	this.create();
  },
  create: function(){
  	if (this.div) return false;
    this.div = new Element('div').setStyle({
      display: 'block',
      position: 'absolute',
      width: isNaN(this.options.size) ? this.options.size : this.options.size + 'px',
      height: isNaN(this.options.size) ? this.options.size : this.options.size + 'px',
      margin: 0,
      padding: 0,
      background: 'transparent url(' + this.options.src + ' ) 0 0 no-repeat',
      overflow: 'hidden'
    });
    document.body.appendChild(this.div);
		if ($('loadAt')) this.alignWith('loadAt');
    return this;
  },
  alignWith: function(el) {
  	if (!$(el)) return this;
  	var xy = $(el).viewportOffset();
  	if (this.div) this.div.setStyle({left: (xy.left + ($(el).getWidth() + 10)) + 'px', top: (xy.top + ($(el).getHeight() * .5) - this.options.size * .5) + 'px'});
  	return this;
  },
  start: function(){
  	if (this.status == 'loading') return false;
  	if (!this.div.visible()) this.show();
 		this.pos = 0;
  	this.loops = 0;
  	this.status = 'loading';
  	this.stopAnim = false;
  	new PeriodicalExecuter(this.anim.bind(this), .1);
  	return this;
  },
  anim: function(pe) {
  	if (!this.div || this.stopAnim) {
  	  pe.stop();
  	  return false;
  	}
  	this.pos -= this.options.size;
  	if (this.pos <= -(this.options.size * 12)) {
  	  this.pos = 0;
  	  this.loops++;
  	  if (this.loops >= this.options.timeout) {
  	    pe.stop();
  	    this.error('timeout');
  	    return false;
  	  }
  	}
  	this.div.setStyle({backgroundPosition: '0 ' + this.pos + 'px'});
   	return true;
  },
  error: function(s) {
  	this.status = s ? s : 'error';	
  	this.stopAnim = true;
  	this.div.setStyle({backgroundPosition: '0 ' + -(this.options.size * 12) + 'px'});
	  Effect.Fade(this.div, {delay: 1.2, duration: 2, afterFinish: this.remove.bind(this)});
  	return this;
  },
  stop: function(navTo) {
  	this.status = 'idle';	
  	this.stopAnim = true;
  	this.remove();
  	if (navTo) window.location.href = navTo;
  	return this;
  },
  show: function() {
  	if (!this.div) return false; 
  	this.div.setStyle({backgroundPosition: '0 0'});
  	this.div.show();
  	return this;
  },
  remove: function() {
  	if (this.status == 'loading') this.stop();
    if (this.div) this.div.remove();
    this.div = null;
    return null;
  },
  hide: function() {
  	this.status = 'hidden';
  	if (this.div) this.div.hide();
  	return this;
  },
  moveTo: function(x, y) {
  	if (this.div) this.div.setStyle({left: x + 'px', top: y + 'px'});
  	return this;
  }
});



/*****************/
/*    Console    */
/*****************/

var Console = Class.create({
	options: null,
	div: null,
	btn: null,
  initialize: function(options) {
    this.options = Object.extend({
   	 	width: 450,
      height: 500,
      left: 'auto',
      top: 'auto',
      right: '0',
      bottom: '0'
    }, options || { });
  	this.create();
  	if (this.btn) Event.observe(this.btn, 'click', this.clear.bindAsEventListener(this));
  },
  create: function(){
  	if (this.div) return false;
  	this.btn = new Element('a', { 'href': '#' }).setStyle({
  		display: 'block',
      position: 'absolute',
      width: isNaN(this.options.width) ? this.options.width : this.options.width + 'px',
      left: 0,
      top: 0,
      padding: '7px',
      backgroundColor: '#222',
      color: '#fff'
  	}).update('clear');
    this.div = new Element('div', {'id': 'consoleDiv'}).setStyle({
      display: 'block',
      position: 'fixed',
      width: isNaN(this.options.width) ? this.options.width : this.options.width + 'px',
      height: isNaN(this.options.height) ? this.options.height : this.options.height + 'px',
      left: ( isNaN(this.options.left) ? this.options.left : this.options.left + 'px' ),
      top: ( isNaN(this.options.top) ? this.options.top : this.options.top + 'px' ),
      bottom: ( isNaN(this.options.bottom) ? this.options.bottom : this.options.bottom + 'px' ),
      right: ( isNaN(this.options.right) ? this.options.right : this.options.right + 'px' ),
      margin: '10px',
      padding: '30px 7px 7px 7px',
      backgroundColor: '#333',
      border: '3px solid #000',
      font: '11px Courier',
      color: '#fff',
      overflowX: 'hidden',
      overflowY: 'auto'
    }).insert(this.btn);
    document.body.appendChild(this.div);
    return this;
  },
  clear: function(evt) {
  	if (evt) evt.stop();
  	this.div.update(this.btn);
  	return this;
  },
  trace: function(msg) {
    if (this.div) this.div.insert(msg + '<br/>');
  	else alert(msg);
  	return this;
  }
});



/*****************/
/*    COOKIE     */
/*****************/
var Cookie = {
  set: function(name, value, daysToExpire) {
    var expire = '';
    if (daysToExpire != undefined) {
      var d = new Date();
      d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));
      expire = '; expires=' + d.toGMTString();
    }
    return (document.cookie = escape(name) + '=' + escape(value || '') + expire);
  },
  get: function(name) {
    var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)'));
    return (cookie ? unescape(cookie[2]) : null);
  },
  erase: function(name) {
    var cookie = Cookie.get(name) || true;
    Cookie.set(name, '', -1);
    return cookie;
  },
  accept: function() {
    if (typeof navigator.cookieEnabled == 'boolean') {
      return navigator.cookieEnabled;
    }
    Cookie.set('_test', '1');
    return (Cookie.erase('_test') === '1');
  }
};



var AIM = Class.create({
	doc: null,
	form: null,
	div: null,
	frame: null,
  options: {},
  observeLoad: null,
	complete: false,
	initialize: function(form, options) {
    this.form = document.getElementById(form);
    this.options = Object.extend({
   	 	name: null,
   	 	show: false,
   	 	name: null,
   	 	onStart: null,
   	 	onComplete: null 	 	
    }, options || { });
    return this;
  },
  setFrame : function() {
		this.options.name = 'f' + Math.floor(Math.random() * 99999);
		this.frame = new Element('iframe', { 'id': this.options.name, 'name': this.options.name, 'href': 'about:blank' });
		this.div = new Element('div').setStyle({
			position: 'absolute',
			display: this.options.show ? 'block' : 'none',
			width: '100px',
			height: '100px',
			overflow: 'hidden'
		}).update(this.frame);
		document.body.appendChild(this.div);
		if (typeof(this.options.onComplete) == 'function') this.frame.onComplete = this.options.onComplete;
		this.observeLoad = this.handleLoaded.bindAsEventListener(this);
		Event.observe(this.frame, 'load', this.observeLoad);
		return this;
	},
	setForm : function() {
		this.form.setAttribute('target', this.options.name);
		return this;
	},
	submit : function() {
		this.setFrame().setForm();
		if (typeof(this.options.onStart) == 'function') return this.options.onStart();
		else return true;
	},
	handleLoaded: function(evt) {
		if (this.frame.contentDocument) {
			this.doc = this.frame.contentDocument;
		} else if (i.contentWindow) {
			this.doc = this.frame.contentWindow.document;
		} else {
			this.doc = window.frames[id].document;
		}
		if (this.doc.location.href == "about:blank") {
			if (this.complete) this.clear();
			return;
		}
		this.complete = true;
		if (typeof(this.frame.onComplete) == 'function') {
			this.frame.onComplete(this.doc.body.innerHTML.stripTags().strip());
		}
	},
	clear: function() {
	  this.frame.remove();
	  this.div.remove();
		this.doc = null;
		this.frame = null;
		this.div = null;
	}	
});
