(function($) {

  /**
   * gzPrettyForms
   *   http://www.gijsvanzon.com/prettyforms
   *
   * Copyright (c) 2010 Gijs van Zon
   * Copyright (c) 2010 Freshheads
   *
   * Built on top of the jQuery 1.4 library
   *   http://jquery.com
   *
   * @name gzPrettyForms
   * @type jQuery
   * @cat Plugins/gzPrettyForms
   *

   *
   * Default Usage:
   * The function works on all inputs, buttons, selects & textareas passed by a selector:
   * $('input[type=text], textarea').gzPrettyForms();
   * Each element is given a class prefix .gzPrettyForms followed by the elements type e.g. .gzPrettyForms-input
   * if clearInput is set to true each input and textarea will get a default value taken from the title attribute
   *

   *
   * Authors: Gijs van Zon MA
   * Return: Object (this)
   * Params:
   *   classPrefix: String ('gzPrettyForms')
   */

  $.fn.gzPrettyForms = function(o) {

    var _this = this;

    $('form').bind('submit', function(e) {
      _this.each(function() {
        $this = $(this);

        if($this.val() == $this.data('value')) {
          $this.val('');
        }
      });
    });

    return this.each(function() {
      new $gzpf(this, o);
    });
  };

  var defaults = {
    classPrefix: 'gzPrettyForms',
    emptyClass: 'gzPrettyForms-empty',
    clearInput: true
  };

  $.gzPrettyForms = function(e, o){

    var self = this;
    var tagName = e.tagName;

    this.options = $.extend({}, defaults, o || {});
    this.element = $(e);

    this.attributes = this.element.attr('title').replace(/^\s+|\s+$/g,"").split(',');
    for(var i = 0; i < this.attributes.length; i++){
      var value = this.attributes[i].split(':');
      if(value[0] == 'value')   this.element.data('value', value[1]);
    };

    if(this.element.attr('title')){
      if(this.element.attr('maxlength')){
        this.element.data('maxlength', this.element.attr('maxlength'));
        if(this.element.data('maxlength') <= 0){
          this.element.data('maxlength', 87255);
        };
      };

      if(this.element.data('value') && this.options.clearInput){
        if(this.element.val() == '') {
          if(this.element.attr('maxlength')){
            this.element.attr('maxlength', 100);
          };

          this.element
            .val(this.element.data('value'))
            .addClass(this.options.emptyClass);
        };

        this.element
          .bind('focus', function() {
            var $this = $(this);
            if($this.val() == $this.data('value')) {
              $this
                .val('')
                .removeClass(self.options.emptyClass);
              if($this.attr('maxlength')){
                $this.attr('maxlength', $this.data('maxlength'));
              };
            };
          })
          .bind('blur', function() {
            var $this = $(this);
            if($this.data('value') != '' && $this.val() == '') {
              if($this.attr('maxlength')){
                $this.attr('maxlength', 100);
              };
              $this
                .val($this.data('value'))
                .addClass(self.options.emptyClass);
            };
          });
      };
    };

    switch(tagName){

      case 'TEXTAREA':
      case 'textarea':
          this.element.addClass(this.options.classPrefix + '-textarea');
        break;

      case 'INPUT':
      case 'input':
        var type = this.element.attr('type');

        switch(type){
          case 'text':
          case 'submit':
          case 'password':
            this.element.addClass(this.options.classPrefix + '-' + type);

            break;
          case 'radio':
          case 'checkbox':
            this.element.addClass(this.options.classPrefix + '-' + type);

            if(!this.element.next().is('label')) this.element.after($('<label><!-- --></label>').addClass('emptyLabel'));

            this.element
              .width(this.element.next().outerWidth())
              .height(this.element.next().outerHeight());

            if(this.element.attr('checked')){
              this.element.next()
                .data('checked', true)
                .addClass('checked');
            }else{
              this.element.next().data('checked', false);
            };

            if(this.element.is(':disabled')){
              this.element.next().addClass('disabled');
            };

            if(type == 'radio'){
              this.element.bind('change', function(e){
                var label = $(this).next();

                $('input[name=' + $(this).attr('name') + ']').attr('checked', false);
                $('input[name=' + $(this).attr('name') + '] + label').removeClass('checked');
                $(this)
                  .attr('checked', 'checked')
                  .next().addClass('checked');
              });
            }else{
              this.element.bind('change', function(e){
                var label = $(this).next();

                if($(this).is(':disabled')){
                  label.addClass('disabled');
                }else{
                  label.removeClass('disabled');
                };

                if($(this).attr('checked')){
                  label
                    .data('checked', true)
                    .addClass('checked');
                }else{
                  label
                    .data('checked', false)
                    .removeClass('checked');
                };
              });
            };
            break;
          case 'file':

            var button = $('<div>')
              .addClass(this.options.classPrefix + '-file-button')
              .html('Bladeren')
              .attr('title', this.element.attr('title'));

            var attributes = this.element.attr('title').replace(/^\s+|\s+$/g,"").split(',');
            for(var i = 0; i < attributes.length; i++){
              var value = attributes[i].split(':');
              if(value[0] == 'route') button.data('route', value[1]);
              if(value[0] == 'target') button.data('target', value[1]);
              if(value[0] == 'multiple') button.data('multiple', value[1]);
            }

            if(button.data('multiple')){
              this.element.after(button);
              this.element.remove();

              new AjaxUpload(button,{
              	action: button.data('route'),
              	name: 'file',
              	onSubmit: function(){
                  button.html('Bezig met uploaden').addClass('uploading');
                  $('#media-upload-form input[type=submit]').attr('disabled', 'disabled');
                  /* Only 1 upload */
                  this.disable();
              	},
              	onComplete: function(file, response){
                  button
                    .html('Klaar met uploaden')
                    .removeClass('uploading gzPrettyForms-file-button')
                    .addClass('gzPrettyForms-file-button-done');

                  var image = $(button.data('target'));

                  if(image.find('ul').length == 0) $(button.data('target')).append('<ul>');

                  var ul  = $(button.data('target')).find('ul');

                  if($(response).length < 1){
                    var li  = $('<li>').html(response);
                  }else{
                    var li = $(response);
                  };
                  li.appendTo(ul);

                  if(parent.window.location != window.location){
                    parent.fancybox.resize($('#iframe').outerHeight());
                  }

                  $('#media-upload-form input[type=submit]').removeAttr('disabled');
              	}
              });
            }else{
              this.element.addClass('gzPrettyForms-file').wrap('<div class="gzPrettyForms-file-holder">');

              var fakeFile = $('<div class="gzPrettyForms-file-fake">');
              var input = $('<input type="text">').gzPrettyForms();
              fakeFile
                .append(input)
                .append(button);
              this.element.after(fakeFile);

              button
                .data('element', this.element)
                .bind('click', function(e){
                  e.preventDefault();
                  $(this).data('element').trigger('click');
                });
              this.element.bind('change', function(){
                input.val($(this).val());
              });
            }
            break;
        };
        break;

      case 'SELECT':
      case 'select':

        var $select = $('<div>')
          .attr('class', this.options.classPrefix + '-select')
          .css('width', this.element.outerWidth());
        this.element.after($select);

        $select.data('position', $select.offset());

        var $optionHolder = $('<div>')
          .attr('class', this.options.classPrefix + '-select-option-holder')
          .css('width', this.element.outerWidth());
        $select.append($optionHolder);

        var $option = $('<p class="gzPrettyForms-select-option">')
          .attr({
            'href': '#'
          })
          .html(this.element.find('option:selected').text());
        $optionHolder.append($option);

        var $list = $('<ul class="gzPrettyForms-select-ul">')
          .css('width', this.element.outerWidth())
          .hide();
        $('body').append($list);

        this.element
          .find('option')
          .each(function(){
            var li = $('<li>');
            $list.append(li);

            var link = $('<a></a>')
              .attr({
                'href': '#'
              })
              .html($(this).text())
              .data({
                'value': $(this).val(),
                'text': $(this).text(),
                'list': $list,
                'selectbox': $(self.element)
              });

            if($(this).attr('selected')){
              link.addClass('selected');
            };

            link.click(function(e){
              e.preventDefault();
              $(this).data('list').find('a').removeClass('selected');
              $(this).addClass('selected');
              $(this).data('selectbox')
                .val($(this).data('value'))
                .trigger('change');
              $option.html($(this).data('text'));
              self.hideSelectBox($option, $list);
            });

            li.append(link);
          });

        $option
          .data('list', $list)
          .data('select', $select)
          .click(function(e){

            $option.data('select').data('position', $select.offset());
            $option.data('list').css({
              'top': $option.data('select').data('position').top + 23,
              'left': $option.data('select').data('position').left
            });

            e.preventDefault();
            if(!$(this).hasClass('active')){
              $(this).addClass('active');
              $(this).data('list').show();
            }
          })
          .hover(
            function(){
              clearTimeout($option.data('timer'));
            },
            function(){
              $option.data('timer', setTimeout(function(){
                self.hideSelectBox($option, $option.data('list'));
              }, 300));
            }
          );
        $list.hover(
          function(){
            clearTimeout($option.data('timer'));
          },
          function(){
            $option.data('timer', setTimeout(function(){
              self.hideSelectBox($option, $option.data('list'));
            }, 300));
          }
        );

        this.element.hide();

        break;
      case 'button':
      case 'BUTTON':
        this.element.addClass(this.options.classPrefix + '-button');
      break;
    };

    if(this.options.initCallback != null){
      this.options.initCallback(this);
    };
  };

  var $gzpf = $.gzPrettyForms;
  $gzpf.fn = $gzpf.prototype = {
    gzPrettyForms: '1.0'
  };

  $gzpf.fn.extend = $gzpf.extend = $.extend;

  $gzpf.fn.extend({
    hideSelectBox: function($listOption, $selectList){
      if($selectList){
        $selectList.hide();
        $listOption.removeClass('active');
      };
    }
  });

})(jQuery);
