/**
 * @author braynej
 */

 
 var Application = Class.create();
 
 Object.extend(Application.prototype, {
 	
	version: 0.1,
	
	initialize: function(){
		this.g = {};
		this.kkeys = [];
		this.konami = "38,38,40,40,37,39,37,39,66,65";
		this.galleries = [
			{
				gallery: 'structure',
				title: 'Dodge',
				description: "Buildings, constructs and man-made objects"
			},
			{
				gallery: 'landscape',
				title: 'Dead Trees',
				description: "Landscapes and natural environments"
			},
			{
				gallery: 'candid',
				title: 'Asbury Park Concert Band',
				description: "People, portraiture and life scenarios"
			},
			{
				gallery: 'fineart',
				title: 'Venus and Cupid: A Study',
				description: "My artwork; Oil Paintings, Charcoal and Acrylics"
			},
			{
				gallery: 'train',
				title: 'NJ Transit EMD F3',
				description: "Trains and all things pertaining to trains"
			},
			{
				gallery: 'wedding',
				title: 'Cold on Dock',
				description: "Weddings"
			}
		];
		
		this.growls = {
			"equipment" : {
				content: "Some of the equipment I use. This is the equipment I currently own, but not necessarily what I've used to capture all of these shots",
				title: "My Photographic Equipment",
				sticky: false,
				className: 'macosx'
			},
			"thumbnails" : {
				content: "You are viewing all images that comprise this site. You may scroll through and click on any image for quick viewing.<br /><br />To close, simply click the link 'hide all thumbnails, which is where 'show all thumbnails was on the bottom left corner.",
				title: "All Photograph View",
				sticky: false,
				className: "macosx"
			}
		};
		this.galleryIndex = 0;
		this.dir = 0;
		this.mover = null;
	},
	
	deleteUser: function(id, email){
		var params = {};
		params.params = {id: id, email: email};
		params.url = 'lib/php/deleteuser.php';
		params.onSuccess = function(res){
			var res = res.responseText.evalJSON();
			var msg = "<p>You have successfully deleted the following account using this email: </p>";
			msg += "<ul><li>Email: " + res.email + "</li></ul>";
			msg += "<p>If you feel this was a mistake, please subscribe again!";
			app.g.growl(msg, {
				header: "Sorry to See You Go!",
				className: "success",
				sticky: true
			});
		};
		app.request(params);
	},
	
	gup: function( name ){
		var name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
		var regexS = "[\\?&]"+name+"=([^&#]*)";
		var regex = new RegExp( regexS );
		var results = regex.exec( window.location.href );
		if( results == null )
			return false;
		else
			return results[1];
	},
	
	growl: function(growl){
		var growl = app.growls[growl];
		app.g.growl(growl.content, {
			header: growl.title,
			className: growl.className,
			sticky: growl. sticky
		});
	},
	
	launchSlideshow: function(gal){
		Lightview.show(gal + "_start");
	},
	
	loadAdminNav: function(){
		
		var links = [
			{title: 'add', id: 'addimage'}, 
			{title: 'peeps', id: 'subscribers'}
		];
		links.each(function(link){
			var li = new Element('li', {
				className: 'nav link',
				id: link.id
			});
			li.observe('click', function(){
				app.loadContent(this, true);
			});
			li.update(link.title);
			$('links').insert(li);
		});
	},
	
	loadGallery: function(){
		$('thumbnails').update();
		var wrapper = new Element('div', {
			className: 'gallerythumbs',
			id: "gallerythumbs"
		});

		var gal = app.galleries[app.galleryIndex];
		
		var a = new Element('a', {
			gallery_start: gal.gallery
		});
		
		a.observe('click', function(){
			app.launchSlideshow($(this).readAttribute('gallery_start'));
			app.g.growl("Loading gallery: <b><i>" + gal.gallery + "</i></b>", {
				header: "Changing Galleries!",
				className: 'macosx'
			});
		});
		var img = new Element('img', {
			src: "lib/img/frame.png",
			title: gal.title,
			alt: gal.title
		});
		var div = new Element('div', {
			style: "background: transparent url(lib/img/" + gal.gallery + "_thumbnail.jpg) no-repeat 5px 5px;"
		});
		div.insert(img);
		a.insert(div);
		wrapper.insert(a);
		
		new Tip(wrapper, "<b>" + gal.description + "</b><br /><br />Click on this image to launch the collection. Click 'play' to run the slideshow or navigate via the arrow links or the arrow keys on your keyboard. Click 'close' or hit 'ESC' to end the slide show.", {
			title: "Gallery: " + gal.gallery,
			stem: 'bottomMiddle',
			hook: {target: 'topMiddle', tip: 'bottomMiddle'}
		});

		$('thumbnails').update(wrapper);
		
		var footertext = "<p><span id='title'>Gallery: </span><span class='alt' id='gallerylabel'>" + gal.gallery + "</span><br /><span class='quiet small' id='subtitle'>[click photo to launch slideshow]</span>";
		var length = $$('.' + gal.gallery).length;
		footertext += "<br /><span id='gallerycount'>" + length + " images total in this gallery</span></p>";
		
		$('galleryfooter').update(footertext);
		new Effect.Appear('thumbnails', {duration: 0.5});
		new Effect.Appear('galleryfooter');
	},
	
	login: function(){
		var code = $('passcode').getValue();
		var params = {};
		params.params = {
			code: code
		};
		params.url = 'lib/php/login.php';
		params.onSuccess = function(res){
			if (res.responseText == true) {
				app.g.growl("You've successfully logged in.", {
					header: "Authenticated!",
					className: "success"
				});
				app.admin = true;
				Tips.hideAll();
				app.loadAdminNav();
			}else{
				app.g.growl("Unsuccessful attempt to log in. If you are not an administrator, please don't try again.", {
					header: "Failure!",
					className: "error"
				});
			}
		};
		app.request(params);
		
	},
	
	moveback: function(){
		var g = $('gallerythumbs');
		app.galleryIndex = (app.galleryIndex <= 0) ? (app.galleries.length - 1) : --app.galleryIndex;
		new Effect.Fade('galleryfooter');
		new Effect.Move(g, {
			x: 1920,
			y: 0,
			afterFinish: function(){
				new Effect.Fade('thumbnails', {
					afterFinish: app.loadGallery,
					duration: 0.1
				});
			}
		});
	},
	
	moveforward: function(){
		var g = $('gallerythumbs');
		app.galleryIndex = (app.galleryIndex < (app.galleries.length - 1)) ? ++app.galleryIndex : 0;
		new Effect.Fade('galleryfooter');
		new Effect.Move(g, {
			x: -1920,
			y: 0,
			afterFinish: function(){
				new Effect.Fade('thumbnails', {
					afterFinish: app.loadGallery,
					duration: 0.1
				});
			}
		});
	},
	
	/*
	move: function(){

		var id = "gallery_" + this.id;
		var g = $(id);
		var offset = g.cumulativeOffset();
		var vp = $('gallerycontainer').getDimensions();
		var count = app.galleryCount[this.id];
		var length = count * 116;
		console.log(length, vp.width)
		if (length > vp.width) {
			app.g.growl('Mouseover to move thumbnails', {
				header: 'On the Move'
			});
			app.mover = new PeriodicalExecuter(function(){
				app.started = true;
				var co = g.cumulativeOffset();
				//console.log("left: ",(co.left), " length: " , (length - 116) * -1)
				if (co.left <= (length - 116) * -1 && app.dir === 0) {
					app.dir = 1;
				}
				else 
					if (co.left >= 0 && app.dir === 1) {
						app.dir = 0;
					}
				var move = (app.dir) ? 116 : -116;
				new Effect.Move(g, {
					x: move,
					y: 0
				});
			}, 2);
			g.observe('mouseout', function(){
				app.dir = 0;
				app.mover.stop();
			});
		}
	},*/
	
	newImageAlert: function(ct){
		if(ct > 0){
			app.g.growl(ct + " new photo(s) added this week!", {
				header: "New Photos Uploaded!",
				className: "macosx",
				life: 20
			});
		}
	},
	
	request: function(params){

		new Ajax.Request(params.url, {
			method: params.method || 'POST',
			evalJS: params.evalJS || false,
			evalJSON: params.evalJSON || false,
			parameters: params.params || null,
			onLoading: params.onLoading || null,
			onSuccess: params.onSuccess || function(res){ window.status = res.status },
			onFailure: params.onFailure || function(){ Controller.onFailure(); },
			onComplete: params.onComplete || null
		});
	},
	
	reset: function(){
		app.galleries.each(function(g){
			$(g).setStyle({left: 0})
		});
		Tips.hideAll();
		app.dir = 0;
		app.mover.stop();
	},
	
	restore: function(){
		$('gallerycontainer').setStyle({display: 'block'});
		$('restore').setStyle({display: 'none'});
	},
	
	run: function(gallery){

		app.g = new k.Growler({location: 'br'});
		app.setTips();
		app.loadGallery();
		app.setGalleryNav();
		if(app.gup('action')){
			if (app.gup('action') === 'unsubscribe') {
				app.deleteUser(app.gup('id'), app.gup('email'));
			}
		}
		
		app.g.growl("Welcome to Jeffrey Brayne Photography. This site is best viewed in Firefox or Safari. Please avoid IE at all costs. If you encounter any bugs or other issues, please contact me and let me know. I would be very appreciative! <a href='mailto:info@jeffreybraynephotography.com'>info@jeffreybraynephotography.com</a>", {
			header: "Site in Beta!",
			className: "macosx",
			life: 15
		});
		
		/* konami code easter egg */
		document.observe('keydown', function(e) {
			app.kkeys.push( e.keyCode );
			if (app.kkeys.toString().indexOf( app.konami ) >= 0 ){
				document.stopObserving('keydown',arguments.callee);
				$('gallerycontainer').setStyle({display: 'none'});
				$('restore').setStyle({display: 'block'});
			}
		});
	},
	
	setGalleryNav: function(){
		$$('.prev').each(function(g){
			$(g).observe('click', app.moveback)
		});

		$$('.next').each(function(g){
			$(g).observe('click', app.moveforward)
		});
	},
	
	setLinks: function(cls, funktion){
		$$(cls).each(function(link){
			link.observe('click', function(){
				funktion(this, false);
			});
		})
	},
 	
	setTips: function(){
		$$('.tip').each(function(tip){
			var div = new Element('div');
			$(tip.readAttribute('target')).childElements().each(function(elm){
				div.insert(elm);
			});
			new Tip(tip, div, {
				fixed: true,
				title: tip.readAttribute('title'),
				showOn: 'click',
				width: 500,
				closeButton: true,
				hideOn: {element: 'closeButton', event: 'click'},
				hook: { tip: 'topLeft', mouse: true },
				offset: { x: 24, y: 44 },
				style: 'default'
			});
			tip.observe('click', function(){
				Tips.hideAll();
			})
		});
	},
	
	stripslashes: function(str) {
        str=str.replace(/\\'/g,'\'');
        str=str.replace(/\\"/g,'"');
        str=str.replace(/\\\\/g,'\\');
        str=str.replace(/\\0/g,'\0');
        return str;
    },
	
	subscribe: function(form){
		if(app.validate()){
			var params = {};
			params.params = $(form).serialize(true);
			params.url = 'lib/php/subscribe.php';
			params.onSuccess = function(res){
				var res = res.responseText.evalJSON();
				var msg = "<p>You've subscribed with the following information:</p>";
				msg += "<ul><li>Name: " + res.username + "</li>";
				msg += "<li>Email: " + res.email + "</li></ul>";
				msg += "<p>If these are not correct, please click <a style='cursor: pointer;' onclick='app.deleteUser(" + res.id + ", \"" + res.email + "\");'>here</a> and try again!</p>"
				app.g.growl(msg, {
					header: "You've Subscribed Successfully!",
					className: 'success',
					life: 15
				});
				Tips.hideAll();
			}
			app.request(params);
		};
		
	},
	
	togglePictures: function(){
		$('pictures').toggle();
		$('showthumbs').toggle();
		$('hidethumbs').toggle();
	},
	
	updater: function(params){
		/**
		 * @description generic interface into Ajax.Updater();
		 */
		var div = params.div || 'content';
		new Ajax.Updater(div, params.url, {
			method: params.method || 'POST',
			parameters: params.params || null,
			evalScripts: params.evalScripts || false,
			onLoading: params.onLoading || null,
			onSuccess: params.onSuccess || null,
			onFailure: params.onFailure || function(){},
			onComplete: params.onComplete || null
		});
	},
	
	validate: function(cb){
		var required = $$('.required');
		var validate = $$('.validate');
		var msg = [];
		var me = this;
		required.each(function(field){
			if($(field).value==''){
				msg.push($(field).name.replace('_', ' ').toUpperCase() + " is Required");
			}else if($(field).readAttribute('datatype')){
				var err = me.validateForm($(field).readAttribute('datatype'), $(field).value);
				if(err) msg.push(err);
			}
		});
		validate.each(function(field){
			if($(field).readAttribute('datatype') && $(field).value!=''){
				var err = me.validateForm($(field).readAttribute('datatype'), $(field).value);
				if(err) msg.push(err);
			}
		});
		if (msg.length > 0) {
			app.g.growl(msg.join('\n'), {
				className: 'error',
				header: "Error!"
			});
            return false;
		}else{
            return true;
        }
	},
	
	validateForm: function(datatype, value){
		var error = "";
		switch(datatype){
			case 'alnum_space':
				var filter = /[0-9a-zA-Z\ \.]/;
				if(!(filter.test(value))){
					error = "You must use only characters or numbers";
				}
				break;
			case 'alnum':
				var filter = /[0-9a-zA-Z]/;
				if(!(filter.test(value))){
					error = "You must use only characters or numbers";
				}
				break;
			case 'alpha_space':
				var filter = /[a-zA-Z\ ]/;
				if(!(filter.test(value))){
					error = "You must use only characters or spaces";
				}
				break;
			case 'alpha':
				var filter = /[a-zA-Z]/;
				if(!(filter.test(value))){
					error = "You must use only characters";
				}
				break;
			case 'digits':
				var filter = /[0-9]/;
				if(!(filter.test(value))){
					error = "You must use only numbers";
				}
				break;
			case 'email':
				var emailFilter= /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;   ///^.+@.+\..{2,3,4,6}$/;
				if (!(emailFilter.test(value))) {
					error = "Please enter a valid email address.";
				}
				var illegalChars= /[\(\)\<\>\,\;\:\\\/\"\[\]]/
				if (value.match(illegalChars)) {
					error = "The email address contains illegal characters.";
				}
				break;
			case 'phone':
				var stripped = value.replace(/[\(\)\.\-\ ]/g, '');
				//strip out acceptable non-numeric characters
				if (isNaN(parseInt(stripped))) {
					error = "The phone number contains illegal characters.";
				}
				if (!(stripped.length == 10)) {
					error = "The phone number is the wrong length. Make sure you included an area code.";
				}
				break;
            case 'phone_3':
                if(isNaN(value)){
                    error = "The phone number must be digits only";
                }
                if(value.length < 3){
                    error = "You must have at least three digits for this part of the phone number";
                }
                break;
             case 'phone_4':
                if(isNaN(value)){
                    error = "The phone number must be digits only";
                }
                if(value.length < 4){
                    error = "You must have at least three digits for this part of the phone number";
                }
                break;
			case 'dropdown':
			    if (value == '') {
			       error = "You didn't choose an option from the drop-down list.";
			    }
				break;
			case 'date':
				var re = /(^\d{4}\-\d{1,2}\-\d{1,2}$)/;
				if(!(re.test(value))) {
					error = "Please enter a valid date: YYYY-MM-DD";
				}
				break;
			case 'zip':
				var zipExp  = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
				if (!(zipExp.test(value))) {
					error = "Please enter a valid zip code.";
				}
				break;
			default:
				error = false;
		}

		return error;
	}
	
 });

