$.widget("wpj.blocks", {
   options: {
      acn: 'edit',
      isSuperuser: false,
      itemsOuterContainerSelector: '#pageBlocksOuterContainer',
      defaultItemSelector: '[data-form-item="0"]',
      addRootItemBtnSelector: '[data-form-custom-add-root]',
      $inputRelations: $('<input type="hidden" name="relations" value="{ }" />'),
      newItemIndex: 0,
      ckeditorConfig: {
         customConfig: '/admin/static/js/ckeditor.js',
         "autoGrow_maxHeight": 0,
         "autoGrow_onStartup": true,
         toolbar: "BasicTable",
         filebrowserBrowseUrl: '/_ckfinder/browse/',
         filebrowserImageBrowseUrl: '/_ckfinder/browse/?rsrcType=Obrázky',
         filebrowserUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Soubory',
         filebrowserImageUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Obrázky'
      }
   },
   _create: function () {
      this._super();

      // append hidden input with block relations to closest form
      // value of this input will also change on successful drag&drop or after adding new item
      this.element.closest('form').append(this.options.$inputRelations);

      // save initial relations to hidden input
      this.refreshRelations();

      // assign default item for creating new items
      this.$defaultItem = $(this.options.defaultItemSelector);

      var that = this;

      // initialize nestedSortable
      this.element.nestedSortable({
         listType: 'ul',
         forcePlaceholderSize: true,
         handle: 'span.drag-drop-mover',
         helper:	'clone',
         items: 'li.blockItem',
         opacity: .6,
         placeholder: 'placeholder',
         revert: 250,
         tabSize: 25,
         tolerance: 'pointer',
         toleranceElement: '> div',
         update: function (event, ui) {
            that.refreshRelations();

            // TODO fix freezing after drop - maybe think of sth better then recreating ckeditor
            var $item = $(ui.item);
            that.reinitializeCkeditor($item);
            $item.find('[data-form-item]').each(function(i,e) {
               that.reinitializeCkeditor($(e));
            });
         }
      });

      initForm({
         selector: this.options.itemsOuterContainerSelector,
         beforeAdd: this.postAddInit
      });

      // add nested items
      this.element.on('click', '[data-form-custom-add]', function(event) {
         event.preventDefault();
         var $item = $(this).closest('[data-form-item]');
         var $container = $item.children('ul:last');
         if (!$container.length) {
            $container = $('<ul></ul>');
            $item.append($container);
         }
         that.postAddInit(function() {
            return that.addItem($container)
         });
         return false;
      });

      // add root items
      $(this.options.addRootItemBtnSelector).on('click', function(event) {
         event.preventDefault();
         that.postAddInit(function() {
            return that.addItem(that.element);
         });
      });

      // refresh block name
      this.element.on('input', 'input[name$="][name]"]', function(event) {
         var $input = $(this);
         var $item = $input.closest('[data-form-item]');
         var $blockHeading = $item.children('.panel-heading');
         $blockHeading.find('[data-block-heading-name]').text($input.val() == '' && !$item.is('[data-form-item-id]') ? '[Nový blok]' : $input.val());
      });

      this.element.on('keydown', null, 'ctrl+enter', function (e) {
         var data = e.data;
         if (data.modif == "ctrl+" && data.special == "return") {
            that.addItem(that.element);

            return false;
         }
      });

      if (this.options.isSuperuser) {
         // refresh block identifier
         this.element.on('input', 'input[name$="][identifier]"]', function (event) {
            var $input = $(this);
            var $blockHeading = $input.closest('[data-form-item]').children('.panel-heading');
            $blockHeading.find('[data-block-heading-identifier]').text($input.val() == '' ? '' : $input.val());
         });
      }

      // initialize ckeditor when block is being opened
      this.element.on('show.bs.collapse', '.blockItem', function(event) {
         var $item = $(event.currentTarget);
         var $textarea = $item.find('[name="data[blocks][' + $item.attr('data-form-item') + '][content]"]');
         if (!$textarea.length || $textarea.attr('name') in CKEDITOR.instances ) {
            return;
         }
         CKEDITOR.replace($textarea.attr('name'), that.options.ckeditorConfig)
      });

      // focus ckeditor after opening block animation
      this.element.on('shown.bs.collapse', '.blockItem', function(event) {
         var $item = $(event.currentTarget);
         var $textarea = $item.find('[name="data[blocks][' + $item.attr('data-form-item') + '][content]"]');
         if (!$textarea.length)
            return;
         if ($textarea.attr('name') in CKEDITOR.instances ) {
            CKEDITOR.instances[$textarea.attr('name')].focus();
         }
      });

      this.element.find('.blockItem:not([data-form-index="0"])').each(function(index, el) {
         that.initPhotos($(el));
      });
   },
   refreshRelations: function() {
      var relations = { };
      this.element.find('[data-form-index]').each(function(index, el) {
         var $item = $(el);
         var $parentItem = $item.parent('ul').parent('[data-form-item]');
         // parentID for already existing blocks, parentIndex (data-form-item) for new blocks
         if ($parentItem.length && !$parentItem.is('[data-form-item-id]')) {
            relations[$item.attr('data-form-item')] = {
               'parentIndex': $parentItem.attr('data-form-item')
            };
         } else {
            relations[$item.attr('data-form-item')] = {
               'parentID': $parentItem.length ? $parentItem.data('form-item-id') : null,
               'parentIndex': $parentItem.length ? $parentItem.attr('data-form-item') : null
            };
         }

      });
      relations = JSON.stringify(relations);
      this.options.$inputRelations.val(relations);
   },
   reinitializeCkeditor: function($item) {
      var $textarea = $item.find('[name="data[blocks][' + $item.attr('data-form-item') + '][content]"]');
      if (!$textarea.length)
         return;
      var $newTextarea = $textarea.clone();
      var $textareaContainer = $textarea.parent();
      for (var instanceName in CKEDITOR.instances) {
         if (CKEDITOR.instances[instanceName]['name'] == $textarea.attr('name')) {
            $newTextarea.html(CKEDITOR.instances[instanceName].getData());
            CKEDITOR.remove(CKEDITOR.instances[instanceName]);
            break;
         }
      }
      $textareaContainer.html($newTextarea);
      CKEDITOR.replace($newTextarea.attr('name'), this.options.ckeditorConfig);
   },
   initPhotos: function($item) {
      $item.find('.photo-select:first').chosen({
         width: '100%',
         placeholder_text_multiple: 'Vyberte obrázky'
      });
   },
   addItem: function($container) {
      var newItemIndex = --this.options.newItemIndex;
      unstyleFormInputs(this.$defaultItem);
      var $newItem = this.$defaultItem.clone();
      $newItem.attr('data-form-item', newItemIndex);
      $newItem.children('[data-target="#collapse_0"]').attr('data-target', '#collapse_' + newItemIndex);
      $newItem.children('#collapse_0').attr('id', 'collapse_' + newItemIndex);
      $newItem.find('[name="data[blocks][0][delete]"]').attr('name', 'data[blocks][' + newItemIndex + '][delete]');
      $newItem.find('[name="data[blocks][0][name]"]').attr('name', 'data[blocks][' + newItemIndex + '][name]');
      $newItem.find('[name="data[blocks][0][identifier]"]').attr('name', 'data[blocks][' + newItemIndex + '][identifier]');
      $newItem.find('[name="data[blocks][0][content]"]').attr('name', 'data[blocks][' + newItemIndex + '][content]');
      $newItem.find('[name="data[blocks][0][photos][]"]').attr('name', 'data[blocks][' + newItemIndex + '][photos][]');
      $container.append($newItem);
      this.refreshRelations();
      $newItem.slideDown(150, function() {
         // animate block form
         $newItem.find('> .panel-heading:first').trigger('click');
      });
      styleFormInputs($newItem);
      this.initPhotos($newItem);
      return $newItem;
   },
   postAddInit: function(original, $container) {
      var $form = original();
      var name = $form.find('textarea').attr('name');
      if (name)
         CKEDITOR.replace(name, this.options.ckeditorConfig);

      // scroll to new item
      $('html,body').animate({
         scrollTop: $form.offset().top
      });
   }
});
