jQuery.email = function($value) {
	return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($value);						
}


jQuery.snippet = function($template, $data) { 
	var $i;
   
   for ($i in $data) {
   	$template = $template.split('{' + $i + '}').join($data[$i]);
   }

   return $template;
}


$.widget('ui.wysiwyg', {

	_init: function() {
   	/*
      http://stackoverflow.com/questions/1498628/how-can-you-integrate-a-custom-file-browser-uploader-with-ckeditor
      http://docs.cksource.com/CKEditor_3.x/Developers_Guide/File_Browser_%28Uploader%29
      http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#constructor
      */

      var $this = this;
      var $input = this.element.find('textarea');
      
      if (this._getData('editor') == null) this._setData('editor', true);

      if (this._getData('editor')) {	
         this.element.find('.textarea').attr('class', 'editor');

         for (var i in CKEDITOR.instances) {
         	CKEDITOR.instances[i].destroy();
         }

         CKEDITOR.replace($input[0], {
            skin : 'kama',
            font_names: 'Arial',
            font_defaultLabel: 'Arial',
            resize_enabled: true,
            resize_maxWidth: '100%',
            resize_minWidth: '100%',
            toolbarCanCollapse: false,
            toolbar : [['Link', 'Unlink', 'Image', '-', 'Format', 'Bold', 'Italic', 'Underline', '-', 'TextColor', 'BulletedList', 'NumberedList', 'Outdent', 'Indent', '-', 'Undo', 'Redo', '-', 'SpellChecker', 'Source']],
            filebrowserBrowseUrl : '/clients/fabric-architecture/php/ckfinder/ckfinder.html',
            filebrowserUploadUrl : '/uploader/upload.php',
            removePlugins: 'elementspath2',
            entities: false,
            dialog_backgroundCoverColor: '#000',
            dialog_backgroundCoverOpacity: 0.75
         });
  
         CKEDITOR.on('instanceReady', function(event) {
            $(window).resize();

            var editor = event.editor;
            var result;
            var interval = setInterval(function(){
               var data = editor.getData();

               if (data == result) return;

               $this.update(data);
               result = editor.getData();
            }, 100);
         });
      }
      else {
         $input.keyup(function() {
            $this.update($(this).val());
         });

         $input.trigger('keyup');
      }
   },

   update: function(value) {
      var data;

      value = value.split("&nbsp;").join(" ");
      value = value.split("\t").join("");
      value = value.split("\r").join("");
      value = value.split("\n").join("");
      value = value.replace(/<[^>]+>/ig, '');
      value = value.split(unescape('%20')).join(" ");
      value = value.split(unescape('%A0')).join(" ");
      value = value.replace(/[ \r\t\n]+$/ig, '');
      this._setData('value', value);
      data = { characters: value.length, words: (value.split(/\b\w+\b/).length - 1) };
      
      this.element.find('.stats .words strong').html(data.words);
      this.element.find('.stats .characters strong').html(data.characters);
   },

   validate: function() {
   	var value = this._getData('value');
      var valid = (value.length >= 2);
   	this.element.toggleClass('error', !valid);
   	return valid;
   }

});

$.ui.wysiwyg.getter = 'validate';


$.widget('ui.uploader', {

	_init: function() {
   	var $this = this;
      var $button;
      
      $button = this.element.find('button.select');
      $button.before("<div class=\"uploader-flash\" style=\"position: absolute; margin-top: " + $button.css('margin-top') + "; margin-left: " + $button.css('margin-left') + "; z-index: 5;\"><div></div></div>");

      $flash = $button.prev();
      $flash.hover(
      	function() { $button.addClass('hover'); },
         function() { $button.removeClass('hover'); }
      );

		var init = {
         upload_url: 'http://www.annaloublog.com/assets/js/swfupload/upload.php',
         flash_url: 'http://www.annaloublog.com/assets/js/swfupload/swfupload.swf',
         file_size_limit: '100 MB',
         button_placeholder: $flash.find('div')[0],
         button_width: $button.innerWidth(),
         button_height: $button.innerHeight(),
         button_window_mode: 'transparent',
         file_dialog_complete_handler: function(file) {
         	upload.startUpload();
         },
         upload_start_handler: function(file) {
            $this.add(file);
         },
         upload_progress_handler: function(file, loaded, total) {
         	$this.progress(file, loaded, total);
         },
         upload_success_handler: function(file, data, response) {
            $this.progress(file, 1, 1);
            $this.uploaded(file, JSON.parse(data));
         },
         post_params: this._getData('post'),
         button_cursor: SWFUpload.CURSOR.HAND
      };
      
      if (this._getData('format') == 'images') {
      	init.file_types = "*.jpg;*.jpeg;*.gif;*.png";
         init.file_types_description = "Images";
      }

      var upload = new SWFUpload(init);

      this._setData('upload', upload);
      this._setData('files', {});
      this.update();
	},

   progress: function(file, loaded, total) {
      var upload = this._getData('upload');
      var progress = loaded / total;
      var $item = this._getData('files')[file.id];

      $item.find('.progress span').css('width', (progress * 100) + '%');
   },

   add: function(file) {
   	var $this = this;
      var template = jQuery.snippet(this.element.find('textarea').val(), {
      	style: "",
      	image: 'http://www.annaloublog.com/assets/images/popup-editor-media-preview.jpg',
         name: file.name.slice(0, 30) + (file.name.length > 30 ? '...' : ''),
         size: Math.round(file.size / 1000) + 'KB',
         url: 'javascript:void(0)'
      });
      var $item;

      this.element.find('ul').append(template);
      $item = this.element.find('ul li:last');
      $item.find('.uploading').show();
      $item.find('.uploading .cancel').click(function() {
         $this.remove($(this).closest('li'));
      });
      $item.data('file', { id: file.id });
      this._getData('files')[file.id] = $item;
      this.update();
   },
   
   remove: function($item) {
   	var upload = this._getData('upload');
   	if ($item.data('file') != null) upload.cancelUpload($item.data('file').id);
      $item.remove();
      this.update();
   },

   uploaded: function(file, data) {
   	var $upload = this._getData('upload');
      file.data = data;
   	$item = this._getData('files')[file.id];
      $item.data('file', file);
      $item.find('.uploading').hide();
   	this.update();
   },

   update: function() {
   	var $this = this;
		var $input = this.element.find('input[type=hidden]').eq(0);
      var data = [];
      var value;
      var $item;

		this.element.find('ul li').each(function() {
      	$item = $(this).find('.remove');
         $item.unbind('click');
         $item.click(function() {
            $this.remove($(this).closest('li'));
         });
         
         value = $(this).data('file');
         if (value == null)
         {
         	value = $(this).find('input[type=hidden]').val();
            
            if (value != null) value = JSON.parse(value);
         }
         else value = value.data;
         data.push(value);
      });
      $input.val(JSON.stringify(data));
      $item = this.element.find('ul');
      $item.sortable({
      	update: function() { $this.update(); }
      });
      $item.toggleClass('items', (data.length > 0));
   },

   validate: function() {
   	return (this._getData('upload').getStats().files_queued == 0);
   }

});

$.ui.uploader.getter = 'validate'; 


$.widget('ui.validate', {

	_init: function() {
   	var $this = this;
   
		this.element.filter('form').submit(function() {
			return $this.validate();										  
		});
      
      this.update();
      
      var $fields = this.fields();
      
      for (var $i = 0; $i < $fields.length; $i++) {
      	$fields.eq($i).trigger('blur');
      }
	},

   update: function() {
   	var $this = this;
      var $fields, $field;
   
   	$fields = this.fields();

		for (var $i = 0; $i < $fields.length; $i++) {
			$field = $fields.eq($i);
         $field.data('validator', this);
			if ($field.data('type') == null) {
         	$field.data('type', $field.attr('type'));
 				$field.unbind();
            $field.focus(function() {
               if ($(this).val() == $(this).attr('title')) {
                  $(this).val('');
                  $this.clone($(this), true);
               }
            });
            $field.blur(function() {
               if ($(this).val().length == 0) {
                  $(this).val($(this).attr('title'));
                  $this.clone($(this), false);
               }
            });
         }
		}
   },

	fields: function() {
		return this.element.find('input, textarea, select');
	},

	clone: function($field, password) {
		var type = $field.data('type');
      var attributes = ['id', 'class', 'style', 'type', 'title', 'name', 'value'];
      var attribute;
      var html;
      var $clone;

		if (type == 'password') {
      	/*
			$clone = $field.clone(true);
			$clone.attr('type', (password ? 'password' : 'text'));
			$clone.insertBefore($field[0]);
			$clone.data('type', type);
         $clone.data('validator', this);
			if (password) $clone.focus();
			$field.remove();
         */
         
         html = "<input type=\"" + (password ? 'password' : 'text') + "\"";
 
         for (var i = 0; i < attributes.length; i++)
         {
         	attribute = $field.attr(attributes[i]);

            if (attribute != null) {
            	html += attributes[i] + "=\"" + attribute + "\"";
            }
         }

         html += "></input>";
 
         $field.after(html);
         $clone = $field.next();
         $field.remove();
         this.update();
         $clone.data('type', type);
         if (password) $clone.focus();
		}
	},

	validate: function() {
		var $fields = this.fields();
      var $field;
      var values = {};
      var value;
      var parts, part;
      var valid;
		var result = true;
      var errors = {};
      var error;

		for ($i = 0; $i < $fields.length; $i++) {
			$field = $fields.eq($i);
         if ($field.data('validator') == this) {
            value = ($field.val() == $field.attr('title') ? '' : $field.val());
            parts = $field.attr('class').split(" ");
            part = null;
   
            for ($j = 0; $j < parts.length; $j++) {
               if (parts[$j].slice(0, 8) == 'validate') {
                  part = parts[$j].slice(9, -1).split(',');
                  break;	
               }
            }

            if (part != null) {
               switch (part[0]) {
                  case 'email': valid = jQuery.email(value); break;
                  default: valid = (value.length >= 1);
               }

               if ($field.is('input[type=text]')) error = 'input-text-error';
               else if ($field.is('input[type=password]')) error = 'input-text-error';
               else if ($field.is('textarea')) error = 'textarea-error';

               $field.parent().toggleClass(error, !valid);
               errors[$field.attr('name')] = !valid;
               values[$field.attr('name')] = value;
   
               if (!valid) result = false;
            }
         }
		}

		if (this._getData('submit') != null)
      {
      	this._getData('submit').apply(this.element[0], [result, errors, values]);
      	return false;
      }

		if (result) this.cleanup();
		return result;
	},
 
   cleanup: function() {
   	var $fields = this.fields();
      var $field;

      for (var i = 0; i < $fields.length; i++) {
         $field = $fields.eq(i);
         if ($field.val() == $field.attr('title')) $field.val('');
      }
   },
   
   submit: function() {
   	this.cleanup();
      this.element[0].submit();
   }

});


$.widget('ui.grid', {

	_init: function() {
   	this.update();
   },

   update: function() {
   	var $this = this;
      var $pagination = this.element.prev('.pagination');
      var $element;

		$element = $pagination.find('.all, .none');
      $element.unbind('click');
      $element.click(function() {
         $this.highlight($(this).hasClass('all'));
      });

      $element = this.element.find('tr:has(td)');
      $element.unbind('mouseup');
      $element.mouseup(function() {
      	$this.highlight($(this));
      });

      $element = this.element.find('a, button');
      $element.unbind('mouseover mouseout');
      $element.mouseover(function() { $(this).addClass('hover'); });
      $element.mouseout(function() { $(this).removeClass('hover'); });

		$element = this.element.find('div.edit a.edit');
      $element.unbind('click');
      $element.click(function() {
      	$this.toggle($(this));
      });

      this.element.find('.edit-form').validate();

      $element = this.element.find('.edit-form button.cancel');
      $element.unbind('click');
      $element.click(function() {
         $this.toggle($(this).closest('td').find('div.edit a.edit'));
      });
      
      $element = this.element.find('.edit-form button[type=button].confirm').click(function() {
      	$this.toggle($(this).closest('td').find('div.edit a.edit'));
         if ($this._getData('submit') !== null) $this._getData('submit').apply($this.element[0], [$(this).closest('td')[0], $(this).closest('.edit-form').find(':text').val()]);
   	});
	},

   toggle: function($element) {
   	$parent = $element.closest('td').find('.edit-form');
      $show = !$parent.is(':visible');
      $(this).closest('.grid').find('.edit-form').hide();
      $(this).closest('.grid').find('div.edit').show();
      $parent.toggle($show);
      $parent = $element.closest('td').find('div.edit');
      $parent.toggle(!$show);
   },
   
   highlight: function($select) {
      $parent = this.element.prevAll('.action').eq(0);
      
      if ($parent.length == 0) return;
   
   	if (typeof $select == 'boolean') {
         this.element.find('tr:has(td)').each(function() {
            $(this).toggleClass('active', $select);
         });
      }
      else {
      	if ($select.find('.hover, .edit-form:visible').length > 0) return;
      	$select.toggleClass('active');
      }

		$items = this.element.find('tr.active');
      $parent.find('.content .left strong span').html($items.length);
      ($items.length > 0 ? $parent.slideDown(400): $parent.slideUp(400));
   },
   
   value: function() {
   	$value = [];
      this.element.find('tr.active').each(function() {
      	$value.push($(this).find('input[name=id]').val());
      });
      return $value;
   }

});

$.ui.grid.getter = 'value'; 


var $controller = {

	popup: function($url) {
   
   	if ($url == null) {
      	$popup = $('#popups .popup-wrapper:last');
         $popup.fadeTo(400, 0, function() {
         	$popup.remove(); 
         });
         return;
      }
      
      if ($url.indexOf('delete') === -1) window.scroll(0, 0);

		$.ajax({
			type: 'POST',
			url: $url,
			cache: false,
			dataType: 'json',
			success: function($data) {
         	var $popup;

            $('#popups').append("<div class=\"popup-wrapper\">" + $data.content + "</div>");
            $controller.update();
            $popup = $('#popups .popup-wrapper:last-child');
            $popup.fadeTo(0, 0);
            $popup.fadeTo(400, 1, function() {
            	jQuery.getScript($data.code, function(){
               });
            });
			}
		 });
	},

	update: function() {
   	$('.dropdown div').each(function() {
         var $element = $(this);
         var $input;
   
         $input = $element.find('select');
         $input.hide();
   
         $options = $input.find('option');
         $data = {};
         $data['results'] = [];
         $data['total'] = $options.length;
   
         for ($i = 0; $i < $options.length; $i++) {
            $option = $options.eq($i);
            $data.results.push({
               'id': $option.val(),
               'name': $option.html()
            });
         }
   
         $element.flexbox($data, {
            width: 450,
            initialValue: $options.filter('[selected]').html(),
            highlightMatches: false,
            maxVisibleRows: 10,
            allowInput: false,
            containerClass: 'items',
            inputClass: 'input',
            arrowClass: 'arrow',
            selectClass: 'active',
            onSelect: function() {
               $input.val($(this).attr('hiddenValue'));
            }
         });
   
         $element.find('.arrow').click(function() {
            $('.dropdown div').each(function() {
               if ($element[0] != this)
               {
                  $(this).css('z-index', 0);
                  $(this).find('.items').hide();
               }
            });
            $element.css('z-index', 100);
         });
      });
   
      if (!jQuery.browser.msie || jQuery.browser.version >= 8) {
      	$('[id^=popup\-][id$=\-overlay]').css('position', 'fixed');
      }

		$('#popup-editor .header .expand').click(function() {
			$item = $('#popup-editor');
			$expand = !$item.hasClass('expanded');
			($expand ? $item.addClass('expanded') : $item.removeClass('expanded'));
			if (!$expand) $(this).css('margin-left', '792px');
			$(window).resize();
		});
      
      $('#popup-confirm .cancel').click(function() {
			$controller.popup();											 
		});

		$(window).trigger('resize');
	}
}


$().ready(function() {
	$('.captcha').each(function() {
   	Recaptcha.create('6LdzxwkAAAAAAFad6Sa3SQs2Ens5_9DZvi_60Ug5', this, {
         theme: 'custom',
			lang: 'en',
         callback: function() { }
      });
   });

   $('#blog #panel .search form').validate();
   $('.rss form').validate();
   $('#blog .detail .comments form').validate();
   $('#blog #panel ul li a[href=javascript\:void\(0\)]').click(function() {
   	$(this).parent().find('ul').slideToggle('slow');
	});

	/*
   if ($('#blog .detail .comments form').length == 0) {
   	$('#blog .detail .description').truncate(300, { trail: ['<a href="javascript:void(0)" class="read-more">Click here to read more</a>', ''] });
   }

   $('#blog .summary li .description').truncate(300, { trail: ['<a href="javascript:void(0)" class="read-more">Click here to read more</a>', ''] });
	*/

	$('#blog .detail .description .read-more, #blog .summary li .description .read-more').click(function() {
   	var $element = $(this).closest('li');
      var url;

      if ($element.length > 0) {
      	$element = $element.find('h2 a');
      }
      else {
      	$element = $(this).closest('.detail')
      	$element = $element.find('h1 a');
      }

      url = $element.attr('href');
      document.location = url;
   });

   $('#blog .video').each(function() {
   	var flash;
      var url;

      url = $(this).find('textarea').val();
      url = url.split('?');
      
      if (url.length == 1) return;
      
   	url = "http://www.youtube.com/v/" + url[1].slice(2) + "&hl=en_US&fs=1&";

      flash = new SWFObject(url, null, 430, 261, '8', '#000000');
      flash.addParam('allowScriptAccess', 'always');
      flash.addParam('allowFullScreen', 'true');
      flash.addParam('wmode', 'transparent');
      flash.write(this);
   });

   if ($('#blog .media').length > 0) {
   	$('#blog .media').each(function() {
      	$(this).find('.thumbnails a').overlay({
            target: '.overlay:first'
         }).gallery({ 
            speed: 800,
            autohide: false
         });
      });

      $('#blog .media .image a').click(function() {
         $(this).closest('.media').find('.thumbnails a:first').trigger('click');
      });
      
      $('#blog .media .view').click(function() {
         $(this).closest('.media').find('.thumbnails a:eq(1)').trigger('click');
      });
   }

	$('ul.edit').each(function() {
		$item = $(this);
		$target = $item.prev().eq(0);
		$item.clone(true).prependTo('body');
		$item.remove();
		$item = $('ul.edit:first');
		$item.data('target', $target);
		$item.data('update', function($item) {
			$target = $item.data('target');
			$position = $target.offset();
			$x = ($position.left + ($item.hasClass('right') ? $target.width() + 10 : -120)) + 'px';
			$y = ($position.top + parseInt($target.css('padding-top'), 10) + parseInt($target.css('margin-top'), 10)) + 'px';
			$item.css('top', $y);
			$item.css('left', $x);									
		});
		$item.data('update')($item);
	});

	$items = $('ul.edit');
   $items.find('a.popup').each(function() {
   	var $button;

      $button = $(this);
      $button.data('href', $button.attr('href'));
      $button.attr('href', 'javascript:void(0)');
      $button.click(function() {
         $controller.popup($(this).data('href'));
      });
   });
   
   $('#control .menu a').click(function() {
		$('#control .menu a').removeClass('active');
      $(this).addClass('active');
   });

   $('#control .menu .button1').click(function() {
      $.cookie('editing', 1, { expires: 10, path: '/', domain: '.annaloublog.com' });
      $('ul.edit').slideDown(200);
   });
   $('#control .menu .button2').click(function() {
   	$.cookie('editing', 0, { expires: 10, path: '/', domain: '.annaloublog.com' });
      $('ul.edit').slideUp(200);
   });

	if ($('#blog').length > 0) {
      if (false && ($.cookie('editing') == '1' || $.cookie('editing') == null)) {
         $('#control .menu .button1').trigger('click');
      }
      else {
         $('#control .menu a').removeClass('active');
         $('#control .menu .button2').addClass('active');
         $items.hide();
      }
   }

	if (jQuery.browser.msie && jQuery.browser.version < 8) {
		$('input').each(function() {
			$input = $(this);
			if ($input.attr('type') == 'text') {
				$input.wrap("<div></div>");	
			}
		});
	}

	$(window).resize(function() {
   	$('ul.edit').each(function() {
         $item = $(this);
         $item.data('update')($item);								
      });
   
		$('#popup-editor.expanded').each(function() {
			$(this).find('.header .expand').	css('margin-left', ($(window).width() - 14) + 'px');													
		});

		$items = $('[id^=popup\-]:not([id$=\-overlay])');
		$items.each(function() {
			$item = $(this);
			if ($item.outerHeight(true) < 500 && $(window).height() >= $item.outerHeight(true)) {
				$y = Math.round(($(window).height() - $item.outerHeight(true)) / 2) + $(window).scrollTop();
				$item.css('top', $y);
			}
			else {
				$item.css('top', ($item.hasClass('expanded') ? 0 : 30));
			}

			$item.css('margin-left', 0);
			$item.css('left', ($item.hasClass('expanded') ? 0 : Math.round(($(window).width() - $item.outerWidth(true)) / 2) + 'px'));
		});

		$items = $('[id^=popup\-][id$=\-overlay]');

      if ($items.css('position') != 'fixed') {
         $items.height($(window).height());
         $width = $().width();
         $height = $().height();
         $items.each(function() {
            $(this).width($width);
            $(this).height($height);			
         });
      }
	});

	$(window).trigger('resize');

	$(window).data('scroll', 0);
	setInterval(function() {
		$scroll = $(window).scrollTop();
		if ($scroll == $(window).data('scroll')) return;
		$(window).trigger('resize');
		$(window).data('scroll', $scroll);
	}, 500);

	$('body').data('font-size', $('body').css('font-size'));
	setInterval(function() {
		$size = $('body').css('font-size');
		if ($size != $('body').data('font-size')) {
			$(window).trigger('resize');
		}
		$('body').data('font-size', $size);
	}, 100);

   $controller.update();
});