(function($) {

  /**
   * gzPrettyForms
   * Copyright (c) 2010 Gijs van Zon
   * Copyright (c) 2010 Freshheads
   *

   *
   * 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 (default .gzPrettyForms) followed by the elements type e.g. .gzPrettyForms-input
   *
   * Examples:
   *   Putting a placeholder text in a input or textarea:
   *    <input type="text" placeholder="placeholder text" />
   *
   *   Creating a single file upload button
   *    <input type="file" route="route-to-upload.php" target="#selector" />
   *
   *   Creating a multiple file upload button
   *    <input type="file" route="route-to-upload.php" target="#selector" multiple="true" />
   *
   *   Creating a dynamic select button with a trigger
   *
   *
   *

   *
   * Authors: Gijs van Zon MA
   * Return: Object (this)
   * Params:
   *  classPrefix: 'gzPrettyForms',
   *  input: {
   *    emptyClass: 'gzPrettyForms-empty'
   *  },
   *  select: {
   *    id: 'id'
   *  }
   */

  $.fn.gzPrettyForms = function(o) {

    var _this = this;

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

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

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

  var defaults = {
    classPrefix: 'gzPrettyForms',
    input: {
      emptyClass: 'gzPrettyForms-empty'
    },
    select: {
      id: 'id'
    }
  };

  $.gzPrettyForms = function(e, s, o) {

    var self = this;
    tagName = e.tagName;

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

    if(!this.element.data('prettyforms')) {
      this.element.data('prettyforms', true);
    } else {
      return true;
    };

    if(this.element.attr('placeholder')) {

      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.val() == '') {
        if(this.element.attr('maxlength')){
          this.element.attr('maxlength', 100);
        };

        this.element
          .val(this.element.attr('placeholder'))
          .addClass(this.options.input.emptyClass);
      };

      this.element
        .bind('focus', function() {
          var $this = $(this);
          if($this.val() == $this.attr('placeholder')) {
            $this
              .val('')
              .removeClass(self.options.input.emptyClass);
            if($this.attr('maxlength')){
              $this.attr('maxlength', $this.data('maxlength'));
            };
          };
        })
        .bind('blur', function() {
          var $this = $(this);
          if($this.attr('placeholder') != '' && $this.val() == '') {
            if($this.attr('maxlength')){
              $this.attr('maxlength', 100);
            };
            $this
              .val($this.attr('placeholder'))
              .addClass(self.options.input.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') + '] + 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'));

            if(this.element.attr('route')) button.data('route', this.element.attr('route'));
            if(this.element.attr('target')) button.data('target', this.element.attr('target'));
            if(this.element.attr('multiple')) button.data('multiple', this.element.attr('multiple'));

            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');
              	},
              	onComplete: function(file, response) {
                  button.html('Bladeren').removeClass('uploading');

                  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);

                  ul.find(s.selector).gzPrettyForms(self.options);
              	}
              });
            } else {
              this.element.addClass('gzPrettyForms-file').wrap('<div class="gzPrettyForms-file-holder">');

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

              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 $selectWrapper = $('<div class="' + this.element.attr('class') + ' ' + this.options.classPrefix + '-select">');
        this.element.wrap($selectWrapper);

        var $select = $('<a></a>')
          .attr('class', 'gzPrettyForms-select-option')
          .css('width', this.element.outerWidth())
          .html('&nbsp;' + this.element.find('option:selected').text())
          .prepend('<span><!-- --></span>');

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

        this.element
          .before($select)
          .addClass('gzPrettyForms-original-select')
          .data('select', $select)
          .bind('change', function(e) {

            var $this = $(this);

            if($this.is(':disabled')) {
              this.data('select').addClass('disabled');
            };
            $this.data('select').html('<span><!-- --></span>&nbsp;' + this.options[this.selectedIndex].text);
          });

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

    switch(tagName) {
      case 'input':
      case 'INPUT':
      case 'select':
      case 'SELECT':

        if(tagName != 'SELECT'){
          var type = this.element.attr('type');

          switch(type) {
            case 'text':
            case 'password':
            break;
            default:
              return false;
          };
        };

        if(this.element.attr('route')) this.element.data('route', this.element.attr('route'));
        if(this.element.attr('target')) this.element.data('target', this.element.attr('target'));
        if(this.element.attr('variable')) this.element.data('id', this.element.attr('variable'));
        if(this.element.attr('trigger')) this.element.data('trigger', this.element.attr('trigger'));
        if(this.element.attr('targetForm')) this.element.data('form', $(this.element.attr('targetForm')));

        if(this.element.data('target')) {
          this.element.data('target', $(this.element.data('target')));
          if(this.element.data('target').length < 1) {
            throw('The target attribute doesn\'t exist');
            return false;
          };
        };

        if(!this.element.data('form') > 0 && !this.element.data('target')) {
          this.element.data('target', this.element.parent());
        };

        if(this.element.data('trigger')) {
          this.element.data('target').hide();
        };

        if(!this.element.data('id')) {
          this.element.data('id', defaults.id);
        };

        this.element.change(function(){

          $this = $(this);

          if($this.data('trigger')) {
            if($this.val() == $this.data('trigger')) {
              $this.data('target').show();
            } else {
              $this.data('target').hide();
            };
          };

          if($this.data('form')) {
            $this.data('form').trigger('submit');
          } else {
            if($this.data('route')) {

              var pos = $this.data('route').indexOf('?');

              $this.data('target').load($this.data('route') + (pos == -1 ? '?' : '&') + $this.data('id') + '=' + $this.val(), function(data){
                $(this).find(s.selector).gzPrettyForms(self.options);
              });
            };
          };
        });
      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({
  });

})(jQuery);
