/**
 * Component used for dynamically adding multiple file input fields.   
 * 
 * Author : vasile.orza
 * 
 *
 * Usage example: 
 *
 * <div id="uploadContainer" data-file-name="attachmentList"
 *                           data-max-file-name-length="50"
 *                           data-file-name-error-msg="Invalid file name"
 *                           data-max-attachments="3"
 *                           data-max-file-size="5242880"></div>
 */
(function($) {
  var defaults = {
    fieldName: "file",
    maxAttachments: 1,
    buttonLabel : "upload",
    maxFileSize : 5242880,
    fileSizeError: "File is too large.",
    maxFileName : 55,
    fileNameError: "File name is too long.",
    fileNameForbiddenChars: /[:*?<>|']|[\[]|[\]]|\//i,
    fileNameForbiddenCharsError: "Invalid file name. File name should not contain any of the following characters: *,:,?,<,>,|,',[,],/,\ ."
  };

  $.fn.fileUpload = function(userOptions) {
    var options = $.extend({}, defaults, {
      fieldName : this.data("field-name"),
      maxAttachments : this.data("max-attachments"),
      buttonLabel : this.data("button-label"),
      maxFileSize : this.data("max-file-size"),
      fileSizeError : this.data("file-size-error-msg"),
      maxFileName : this.data("max-file-name"),
      fileNameError : this.data("file-name-error-msg"),
      fileNameForbiddenCharsError : this.data("file-name-forbidden-chars-error-msg")
    });

    return this.addClass("fileUpload clearfix").each(function() {
      var $container = $(this);
      // generate 'add file' button
      $("<div>").addClass("uploadButton")
                .append(
                    // the extra space is a Chrome fix
                    $("<button>").addClass("textButton").html(options.buttonLabel).append(" ")
                ).appendTo(this);
      // generate container for the 'added files' list
      $("<ul>").addClass("left clear").appendTo(this);

      $container.bind("addFileInput", function() {
        var noAttachments = $container.find("ul").children().length;
        options.maxAttachments = parseInt(options.maxAttachments);
        if (options.maxAttachments <= noAttachments ){
          $container.css("opacity",'0.7');
          $container.find("button.textButton").attr('disabled','disabled');
          return false;
        }
        // generate associated 'file'
        var $newInput = $("<input>").attr("type", "file").attr("name", options.fieldName).change(function() {
          // clear old error messages
          $container.find('span.errorMsg').remove();
          // file size validation
          var $fileInput = $(this);
          if($fileInput[0].files && $fileInput[0].files[0].size > options.maxFileSize){
            $('<span>').html(options.fileSizeError).addClass("errorMsg").appendTo($container);
            $fileInput.val("");
            return;
          }
          // file name validation
          var fileName = $fileInput.val().split("\\").pop();
          //file name invalid characters validation
          var pos = fileName.search(options.fileNameForbiddenChars);
          if (pos != -1){
        	  $('<span>').html(options.fileNameForbiddenCharsError).addClass("errorMsg").appendTo($container);
        	  $fileInput.val("");
        	  return;
          }
          
          if(fileName.length > options.maxFileName) {
            $('<span>').html(options.fileNameError).addClass("errorMsg").appendTo($container);
            $fileInput.val("");
            return;
          }
          // generate display name for the file
          if(fileName.length > 40) {
            fileName = fileName.substring(0,34)+ "...";
          }
          var $fileLabel = $("<span>").html(fileName);
          var $removeLink = $("<a>").html("x").click(function() {
            $(this).parent().toggle(150, function() {
              $(this).remove();
              $container.css("opacity",'1');
              $container.trigger("addFileInput");

            });
            return false;
          });
          // move to the 'selected files' container
          $("<li>").append($removeLink)
                   .append($fileLabel)
                   .append($fileInput)
                   .appendTo($container.find("ul"))

          // reset new 'file input' to the parent 'button container'
          $fileInput.trigger("addFileInput");
        });
				
        $(this).find(".uploadButton").append($newInput);

      }).trigger("addFileInput");
    });
  };
})(jQuery);

