/**
 * Redmine - project management software
 * Copyright (C) 2006-  Jean-Philippe Lang
 * This code is released under the GNU General Public License.
 */

var contextMenuObserving;

function contextMenuRightClick(event) {
  var target = $(event.target);
  if (target.is('a:not(.js-contextmenu)')) {return;}
  var tr = target.closest('.hascontextmenu').first();
  if (tr.length < 1) {return;}
  event.preventDefault();
  if (!contextMenuIsSelected(tr)) {
    contextMenuUnselectAll();
    contextMenuAddSelection(tr);
    contextMenuSetLastSelected(tr);
  }
  contextMenuShow(event);
}

function contextMenuClick(event) {
  var target = $(event.target);
  var lastSelected;

  if (target.is('a') && target.hasClass('submenu')) {
    event.preventDefault();
    return;
  }
  contextMenuHide();
  if (target.is('a') || target.is('img')) { return; }
  if (event.which == 1 || (navigator.appVersion.match(/\bMSIE\b/))) {
    var tr = target.closest('.hascontextmenu').first();
    if (tr.length > 0) {
      // a row was clicked
      if (target.is('td.checkbox')) {
    	// the td containing the checkbox was clicked, toggle the checkbox
    	target = target.find('input').first();
    	target.prop("checked", !target.prop("checked"));
      }
      if (target.is('input')) {
        // a checkbox may be clicked
        if (target.prop('checked')) {
          tr.addClass('context-menu-selection');
        } else {
          tr.removeClass('context-menu-selection');
        }
      } else {
        if (event.ctrlKey || event.metaKey) {
          contextMenuToggleSelection(tr);
          contextMenuClearDocumentSelection();
        } else if (event.shiftKey) {
          lastSelected = contextMenuLastSelected();
          if (lastSelected.length) {
            var toggling = false;
            $('.hascontextmenu').each(function(){
              $elm = $(this)
              if (!$elm.is(lastSelected) && (toggling || $elm.is(tr))) {
                contextMenuAddSelection($(this));
                contextMenuClearDocumentSelection();
              }
              if ($elm.is(lastSelected) !== $elm.is(tr)) {
                toggling = !toggling;
              }
            });
          } else {
            contextMenuAddSelection(tr);
          }
        } else {
          contextMenuUnselectAll();
          contextMenuAddSelection(tr);
        }
        contextMenuSetLastSelected(tr);
      }
    } else {
      // click is outside the rows
      if (target.is('a') && (target.hasClass('disabled') || target.hasClass('submenu'))) {
        event.preventDefault();
      } else if (target.is('.toggle-selection') || target.is('.ui-dialog *') || $('#ajax-modal').is(':visible')) {
        // nop
      } else {
        contextMenuUnselectAll();
      }
    }
  }
}

function contextMenuCreate() {
  if ($('#context-menu').length < 1) {
    var menu = document.createElement("div");
    menu.setAttribute("id", "context-menu");
    menu.setAttribute("style", "display:none;");
    document.getElementById("content").appendChild(menu);
  }
}

function contextMenuShow(event) {
  var mouse_x = event.pageX;
  var mouse_y = event.pageY;
  var mouse_y_c = event.clientY;
  var render_x = mouse_x;
  var render_y = mouse_y;
  var dims;
  var menu_width;
  var menu_height;
  var window_width;
  var window_height;
  var max_width;
  var max_height;
  var url;

  $('#context-menu').css('left', (render_x + 'px'));
  $('#context-menu').css('top', (render_y + 'px'));
  $('#context-menu').html('');

  url = $(event.target).parents('form').first().data('cm-url');
  if (url == null) {alert('no url'); return;}

  $.ajax({
    url: url,
    data: $(event.target).parents('form').first().serialize(),
    success: function(data, textStatus, jqXHR) {
      $('#context-menu').html(data);
      menu_width = $('#context-menu').width();
      menu_height = $('#context-menu').height();
      max_width = mouse_x + 2*menu_width;
      max_height = mouse_y_c + menu_height;

      var ws = window_size();
      window_width = ws.width;
      window_height = ws.height;

      /* display the menu above and/or to the left of the click if needed */
      if (max_width > window_width) {
       render_x -= menu_width;
       $('#context-menu').addClass('reverse-x');
      } else {
       $('#context-menu').removeClass('reverse-x');
      }

      if (max_height > window_height) {
       render_y -= menu_height;
       $('#context-menu').addClass('reverse-y');
        // adding class for submenu
        if (mouse_y_c < 325) {
          $('#context-menu .folder').addClass('down');
        }
      } else {
        // adding class for submenu
        if (window_height - mouse_y_c < 345) {
          $('#context-menu .folder').addClass('up');
        }
        $('#context-menu').removeClass('reverse-y');
      }

      if (render_x <= 0) render_x = 1;
      if (render_y <= 0) render_y = 1;
      $('#context-menu').css('left', (render_x + 'px'));
      $('#context-menu').css('top', (render_y + 'px'));
      $('#context-menu').show();

      //if (window.parseStylesheets) { window.parseStylesheets(); } // IE
    }
  });
}

function contextMenuSetLastSelected(tr) {
  $('.cm-last').removeClass('cm-last');
  tr.addClass('cm-last');
}

function contextMenuLastSelected() {
  return $('.cm-last').first();
}

function contextMenuUnselectAll() {
  $('input[type=checkbox].toggle-selection').prop('checked', false);
  $('.hascontextmenu').each(function(){
    contextMenuRemoveSelection($(this));
  });
  $('.cm-last').removeClass('cm-last');
}

function contextMenuHide() {
  $('#context-menu').hide();
}

function contextMenuToggleSelection(tr) {
  if (contextMenuIsSelected(tr)) {
    contextMenuRemoveSelection(tr);
  } else {
    contextMenuAddSelection(tr);
  }
}

function contextMenuAddSelection(tr) {
  tr.addClass('context-menu-selection');
  contextMenuCheckSelectionBox(tr, true);
}

function contextMenuRemoveSelection(tr) {
  tr.removeClass('context-menu-selection');
  contextMenuCheckSelectionBox(tr, false);
}

function contextMenuIsSelected(tr) {
  return tr.hasClass('context-menu-selection');
}

function contextMenuCheckSelectionBox(tr, checked) {
  tr.find('input[type=checkbox]').prop('checked', checked);
}

function contextMenuClearDocumentSelection() {
  // TODO
  if (document.selection) {
    document.selection.empty(); // IE
  } else {
    window.getSelection().removeAllRanges();
  }
}

function contextMenuInit() {
  contextMenuCreate();
  contextMenuUnselectAll();

  if (!contextMenuObserving) {
    $(document).click(contextMenuClick);
    $(document).contextmenu(contextMenuRightClick);
    $(document).on('click', '.js-contextmenu', contextMenuRightClick);
    contextMenuObserving = true;
  }
}

function toggleIssuesSelection(el) {
  var checked = $(this).prop('checked');
  var boxes = $(this).parents('table').find('input[name=ids\\[\\]]');
  boxes.prop('checked', checked).parents('.hascontextmenu').toggleClass('context-menu-selection', checked);
}

function window_size() {
  var w;
  var h;
  if (window.innerWidth) {
    w = window.innerWidth;
    h = window.innerHeight;
  } else if (document.documentElement) {
    w = document.documentElement.clientWidth;
    h = document.documentElement.clientHeight;
  } else {
    w = document.body.clientWidth;
    h = document.body.clientHeight;
  }
  return {width: w, height: h};
}

$(document).ready(function(){
  contextMenuInit();
  $('input[type=checkbox].toggle-selection').on('change', toggleIssuesSelection);
});
