'use strict';

/**
 * CONSTANTS
 */
var BASE_RANDOM_NUMBER = 25,
  CUBE_SELECTOR = "#cube-wall",
  POPOVER_SELECTOR = "[data-toggle='popover']",
  SEARCH_FIELD_NAME = 'search_field',
  CUBE_SELECTOR_WRAP = '.cubes_inner_wrap',
  GRID_HEIGHT = 14,
  GRID_WIDTH = 30,
  FADE_TIME = 600,
  POPOVER_HEIGHT = 450;

$(document).ready(function(){
  if ($('#user_search_block').length > 0 && $('.section_environment').length == 0)  {
    initPlaceOfCubes();
  }
  $('[data-toggle="popover"]').popover({title: "<span class=\"usr_surname\">Фондар</span><span class=\"usr_name\">Вікторія Тараневська <a href=\"#\" class=\"round_link\"><i class=\"icon icon_fb\"></i></span>", content: "<div class=\"usr_contributions\">Внесків 3</div><div class=\"usr_funds\"><div class=\"usr_funds_value\">на суму:  14 200 UAH</div></div><div class=\"usr_volunteering\">Волонтерство 2</div>", html: true, placement: "top"});
});

/**
 * @function initPlaceOfCubes - function for drawing cubes(images) on place(some element)
 */
function initPlaceOfCubes() {
  $.ajax({
    url: $("#current_locale").val()+'/builder_users_squares',
    method: "GET"
  }).done(function (data) {
    var sourceData = data;
    var listSize = getListSourceSize(sourceData);
    var baseHeight = _.max(listSize.listOfHeight);
    //var baseWidth = _.max(listSize.listOfWidth) + 15;
    var maxWidth = _.max(listSize.listOfWidth);
    var k = $(CUBE_SELECTOR).width()/$(CUBE_SELECTOR).height();
    var baseWidth = k*(maxWidth > baseHeight ? maxWidth : baseHeight);
    
    initAutocomplete(sourceData, SEARCH_FIELD_NAME);
    searchFounder();
    generateCubeHTML(sourceData, baseHeight, baseWidth);
    initPopover($(POPOVER_SELECTOR));
    initDraggable($(CUBE_SELECTOR));
  }).fail(function (msg) {
    console.error(msg);
  });
}

/**
 * @function getListSourceSize - function for getting list of height and width
 * @param sourceData
 * @returns {{listOfHeight: Array, listOfWidth: Array}}
 */
function getListSourceSize(sourceData) {
  var listSize = {
    listOfHeight: [],
    listOfWidth: []
  };
  _.map(sourceData, function (item) {
    listSize.listOfHeight.push(item.height);
    listSize.listOfWidth.push(item.width);
  })
  return listSize;
}

/**
 * @function gratitudeCube - service for managing popup (gratitude)
 */
var gratitudeCubeElement = {
  element: null,
  id: null,
  get: function() {
    this.element = $('[data-id=' + this.id + ']');
    return this.element;
  },
  set: function(id) {
    this.id = id;
  }
};

/**
 * @function roundedToNumber - function for rounding to some(optional) number
 * @param currentNumber - {Int}, number for rounding
 * @param roundedNumber - {Int}, number to round
 */
function roundedToNumber(currentNumber, roundedNumber) {
  var resultWidth = Math.ceil(currentNumber/roundedNumber) * roundedNumber;
  return resultWidth;
}

/**
 * @function initDraggable - function for initialization draggable property
 * @param selector - {JQuery Object}, selector using for draggable
 */
function initDraggable() {
  $(CUBE_SELECTOR).draggable({
    scroll: false,
    cursor: 'move'});
}

/**
 * @function initPopover - function for initialization popover
 * @param selector - {JQuery Object}, popover selector
 */
function initPopover(selector) {
  selector.each(function () {
    var $elem = $(this);
    $elem.popover({
      placement: 'top auto',
      html: true,
      container: $elem
    });
  });
  
  selector.on('shown.bs.popover', function () {
    $('.default_tip').addClass('hidden_tip');
    var id = $(this).parents('.cell').attr('data-id');
    ($(CUBE_SELECTOR).find('.cell[data-id]:not([data-id='+id+'])')).find(POPOVER_SELECTOR).popover('hide');
  });
  
  $('body').on('click', function (e) {
    //did not click a popover toggle, or icon in popover toggle, or popover
    if ($(e.target).data('toggle') !== 'popover'
      && $(e.target).parents('[data-toggle="popover"]').length === 0
      && $(e.target).parents('.popover.in').length === 0) {
      $('[data-toggle="popover"]').popover('hide');
    }
  });
}

function spiral(n) {
  var r = Math.floor((Math.sqrt(n + 1) - 1) / 2) + 1;
  var p = (8 * r * (r - 1)) / 2;
  var en = r * 2;
  var a = (1 + n - p) % (r * 8);
  var pos = [0, 0, r];
  switch (Math.floor(a / (r * 2))) {
    case 0:
    {
      pos[0] = a - r;
      pos[1] = -r;
    }
      break;
    case 1:
    {
      pos[0] = r;
      pos[1] = (a % en) - r;
      
    }
      break;
    case 2:
    {
      pos[0] = r - (a % en);
      pos[1] = r;
    }
      break;
    case 3:
    {
      pos[0] = -r;
      pos[1] = r - (a % en);
    }
      break;
  }
  return pos;
}

/**
 * @function generateCubeHTML - function for generating html for cube map
 * @param sourceData - {Array}, array of cube's object
 * @param baseHeight - {Int}, height of all cubes
 */
function generateCubeHTML(sourceData, baseHeight, baseWidth) {
  var gratitudeElement,
    width,
    iWeight,
    iHeight,
    source,
    x0 = $(CUBE_SELECTOR).width()/2 - 80,
    y0 = $(CUBE_SELECTOR).height()/2,
    x, y,
    listOfAlign = ['left', 'center', 'right'];
  sourceData = sourceData.concat(new Array(Math.ceil(sourceData.length*0.001)));
  //sort array
  sourceData = _.shuffle(sourceData);
  gratitudeElement =
    "<div class='cell' style='width: {width}px; height: {height}px; top: {top}px; left: {left}px; ' data-id='{id}' data-folder='{folder_name}'>" +
    "<div style='display: inline-block; position: relative; '>" +
    "<div class='default_tip' style='position: absolute; bottom: calc(100% + 20px); left: {iHalfWeight}px; z-index: 999'> " +
    "<div class='default_tip_content'> " +
    "<div class='default_tip_title'>{gratitude_title} </div> <div class='default_tip_text'>{gratitude_phrase}</div> " +
    "<div class='vertical_soc {gratitude_share} '> " +
    "<a href=\"{link_share_facebook}\" class='circle_link soc_btn_fb hidden_link_share_facebook'><span><i class='icon icon_fb'></i></span> <i class='icon icon_right_arrow_lg'></i></a> " +
    "<a href=\"{link_share_twitter}\" class='circle_link soc_btn_tw hidden_link_share_twitter'><span><i class='icon icon_tw'></i></span> <i class='icon icon_right_arrow_lg'></i></a> " +
    "<a href=\"{link_share_google}\" class='circle_link soc_btn_google hidden_link_share_google'><span><i class='icon icon_google'></i></span> <i class='icon icon_right_arrow_lg'></i></a> " +
    "</div> " +
    "</div> " +
    "</div>" +
    "<div data-toggle='popover' " +
    "title='<span class=\"usr_surname\">{role}</span>" +
    "<span class=\"usr_name\">{name} " +
    "<a href=\"{facebook}\" class=\"round_link\"><i class=\"icon icon_fb\"></i></a>" +
    "</span>' " +
    "data-content='<div class=\"usr_contributions\">{contributions_title} {contributions_value}</div>" +
    "<div class=\"usr_funds\">{funds_title}<div class=\"usr_funds_value\">{funds_value} {funds_currency}</div>" +
    "</div>" +
    "<div class=\"usr_contributions usr_volunteer\">{contributions_volunteer_title} {contributions_volunteer_value}</div>' " +
    "class='usr-info'>" +
    "<img width='{iWeight}' height='{iHeight}' src='{source}' alt=''/>" +
    "</div>" +
    "</div>" +
    "</div>";
  
  _.map(sourceData, function (item, i) {
    if (!Boolean(item)) {
      var pos = spiral(i);
      x = x0 + baseWidth * pos[0];
      y = y0 + baseHeight * pos[1];
      $(CUBE_SELECTOR).append('<div class="cell" style="width: '+ baseWidth +'px; height: '+ baseHeight +'px; top: '+ y +'px; left: '+ x +'px; "></div>');
      return;
    }
    var fullElement = getElement(item.info.links.facebook);
    iHeight = item.height;
    iWeight = item.width;
    width = iWeight;
    source = item.source || ''; //set default image
    if (item.id == item.user_donate) {
      gratitudeCubeElement.set(item.user_donate);
      fullElement = gratitudeElement
        .replace(/\{gratitude_title\}/, item.title)
        .replace(/\{gratitude_phrase\}/, item.phrase)
        .replace(/\{gratitude_share\}/, getGratitudeShareClass(item.is_share))
    }
    
    //customize social network links
    _.map(item.info.links, function(link, social) {
      var socialReg = new RegExp('\{' + social + '\}');
      fullElement = fullElement.replace(socialReg, link);
    });
    
    //customize social network links by sharing
    _.map(item.socials, function(link, social) {
      var socialReg = new RegExp('\{' + social + '\}'),
        socialRegClassName = 'hidden_' + social;
      if ($.trim(link).length != 0) {
        fullElement = fullElement
          .replace(socialReg, link)
          .replace(socialRegClassName, '');
      }
    });
    var pos = spiral(i);
    x = x0 + baseWidth * pos[0];
    y = y0 + baseHeight * pos[1];
    fullElement = fullElement
      .replace(/\{id\}/, item.id)
      .replace(/\{folder_name\}/, item.folder_name)
      .replace(/\{height\}/, baseHeight)
      .replace(/\{width\}/, baseWidth)
      .replace(/\{top\}/, y)
      .replace(/\{left\}/, x)
      .replace(/\{textAlign\}/, _.sample(listOfAlign))
      .replace(/\{iHeight\}/g, iHeight)
      .replace(/\{iHalfWeight\}/, -35 + iWeight/2)
      .replace(/\{iWeight\}/, iWeight)
      .replace(/\{source\}/, source)
      .replace(/\{name\}/, item.info.name.replace("'", "&#039;"))
      .replace(/\{role\}/, item.info.role)
      .replace(/\{contributions_title\}/, item.info.contributions.benefactor.title)
      .replace(/\{contributions_value\}/, item.info.contributions.benefactor.value)
      .replace(/\{contributions_volunteer_title\}/, item.info.contributions.volunteer.title)
      .replace(/\{contributions_volunteer_value\}/, item.info.contributions.volunteer.value)
      .replace(/\{funds_title\}/, item.info.funds.title)
      .replace(/\{funds_value\}/, item.info.funds.value)
      .replace(/\{funds_currency\}/, item.info.funds.currency);
    
    $(CUBE_SELECTOR).append(fullElement);
  });
}

function getElement(fbLink) {
  fbLink = Boolean(fbLink) ? "<a href=\"{facebook}\" class=\"round_link\"><i class=\"icon icon_fb\"></i></a>" : '';
  return "<div class='cell' style='width: {width}px; height: {height}px; top: {top}px; left: {left}px; text-align: {textAlign}' data-id='{id}' data-folder='{folder_name}'>" +
    "<div style='display: inline-block;'>" +
    "<div data-toggle='popover' data-trigger='hover' " +
    "title='<span class=\"usr_surname\">{role}</span>" +
    "<span class=\"usr_name\">{name} " +
    fbLink +
    "</span>' " +
    "data-content='<div class=\"usr_contributions\">{contributions_title} {contributions_value}</div>" +
    "<div class=\"usr_funds\">{funds_title}<div class=\"usr_funds_value\">{funds_value} {funds_currency}</div>" +
    "</div>" +
    "<div class=\"usr_contributions usr_volunteer\">{contributions_volunteer_title} {contributions_volunteer_value}</div>' " +
    "class='usr-info'>" +
    "<img width='{iWeight}' height='{iHeight}' src='{source}' alt=''/>" +
    "</div>" +
    "</div>" +
    "</div>";
}

function getGratitudeShareClass(isShare) {
  var className = '';
  if (!isShare) {
    className = 'hidden_share';
  }
  return className;
}

/**
 * @function initAutocomplete - function for initialization auto complete by input
 * @param data - {Array}, array of cube's object
 * @param selector - {JQuery Object}, input selector
 */
function initAutocomplete(data, selector) {
  data = data || [];
  var input = document.getElementById(selector);
  var listByNameFounders = _.map(data, function(item, i) {
    return {
      value: item.info.name,
      data: item
    };
  });
  
  $('#' + selector).autocomplete({
    lookup: listByNameFounders,
    onSelect: function (suggestion) {
      if (window.currentSuggestion == suggestion.data.id) {
        return;
      }
      window.currentSuggestion = suggestion.data.id;
      var element = $('[data-id=' + suggestion.data.id + ']'),
        scrollingContainer = $(CUBE_SELECTOR),
        position = element.position();
      centralizeContainer(scrollingContainer, position, element.width());
      setTimeout(function () {
        //hide popovers except selected
        (scrollingContainer.find('.cell[data-id]:not([data-id=' + suggestion.data.id + '])')).find(POPOVER_SELECTOR).popover('hide');
      }, 0);
      
      setTimeout(function () {
        //show selected item (popover)
        element.find(POPOVER_SELECTOR).popover('show');
      }, FADE_TIME);
    },
    onSearchComplete: function (query, suggestion) {
      window.suggestion = suggestion;
      if (window.query !== query) {
        window.query = query;
        window.currentSuggestion = -1;
      }
    }
  });
}

/**
 * @function getCssValueByInt - function for getting value (value type like number) and parse it into Int type
 * @param selector - {JQuery Object}, selector
 */
function  getCssValueByInt(selector, property) {
  return parseInt(selector.css(property));
}

/**
 * @function centralizeContainer - function for centralizing container
 * @param container - {JQuery Object}, selector
 * @param position - {Object}, which consists keys "left" and "top"
 */
function centralizeContainer(container, position, correctWidth) {
  correctWidth = correctWidth || 0;
  var top = roundedToNumber((getCssValueByInt(container.parent(), 'margin-top') + POPOVER_HEIGHT - parseInt(position.top)), GRID_HEIGHT),
    left = roundedToNumber((container.width()/2 - correctWidth - parseInt(position.left)), GRID_WIDTH);
  container.animate({ 'left': left + 'px', 'top': top + 'px' }, FADE_TIME);
  
}

/**
 * @function searchFounder - function for searching by founder name
 */
function searchFounder() {
  $('#user_search_btn').on('click', function() {
    searching();
  });
  
  $('#' + SEARCH_FIELD_NAME).keypress(function(event) {
    if(event.which == 13) {
      _.map($('.autocomplete-suggestion'), function(item) {
        if ($('#' + SEARCH_FIELD_NAME).val() === $(item).text()) {
          $(item).trigger('click');
        }
      });
      searching();
    }
  });
  function searching() {
    window.currentSuggestion = -1;
    $('#' + SEARCH_FIELD_NAME).focus();
  }
}