// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

var zd = { // used by new modular JS, but needs to be defined before data is pushed into it within the HTML body
  jsInitializers: [],
  jsData: {}
};

var standard_blind_options = {duration: "0.25"};

var items = {}; // For rule data

// Ticket functions - create/edit

//function zd_highlight(p) {
//  if (p) { p.className = (p.value==0 || p.value=='') ? "highlight" : "" }
//}

function render_per_type() {
  if ($("ticket_ticket_type_id")) {
    if ($("ticket_linked_id")) { set_visibility("ticket_link", ($F("ticket_ticket_type_id")=="2")) }
    if ($("ticket_date")) { set_visibility("ticket_date", ($F("ticket_ticket_type_id")=="4")) }
    //if ($("ticket_due_date_1i")) { set_visibility("ticket_date", ($F("ticket_ticket_type_id")=="4")) }
  }
}

// Assignee select - ticket create/edit
function assignee_select(group_id, user_id) {
  group_id = Number(group_id);

  var group;
  var previous;
  var select = $('ticket_assignee_id');
  select.update(new Element('option')); // clear current items in the list, but keep a blank option

  if (group_id >= 0 && typeof(group = groups.find(function(group){ return(group.id === group_id); })) !== 'undefined') {
    // Create an option for every agent of the selected group
    agents.each(function (agent, index) { // just get the agents in this group first.
      if (typeof(group.users.find(function (user) {return(user === agent.id);})) !== 'undefined' ) { // only agents within this group
        var option = new Element('option', {value: agent.id}).update(agent.name);
        if (Number(user_id) === agent.id) {
          option.writeAttribute({selected: 'selected'}); // select the current user if he's one of the potential assignees
        }
        select.insert(option);
      }
    });
    select.enable();
  }
  else {
    select.options.selectedIndex = 0;
    select.disable();
  }

  select.setStyle('width', 'auto'); // hack for IE bug: if #ticket_assignee_id is populated with a name that makes it wider, it stretchs through/behind any selects to its right. see PT#3273178
}

function update_properties(assignee_id) {
  // Highlight missing properties on ticket form
  if ($("ticket_group_id") && $("ticket_group_id").type=="select-one") {
    if ($F("ticket_group_id") == '') {
      }
    else {
      if ($F("ticket_assignee_id")=='') { assignee_select($F("ticket_group_id"), assignee_id) } }
  }
  render_per_type();
  return true;
}

// Highlights agents in ticket cc list
function highlightAgents(){
  // Parse CC-List
  var ccusers = $$('#facebook-list li.choice');
  for(index = 0; index < ccusers.length; index++){
    var choiceId = ccusers[index].readAttribute('choice_id');

    if(typeof(agents.find(function(agent) {return (agent.id === Number(choiceId)); })) !== 'undefined') {
      $$('#facebook-list li.choice')[index].addClassName('agent');
    }
  }

  // Observe changes
  var first_ul = $$('#facebook-list ul.multi_value_field')[0];
  if (first_ul){
    first_ul.observe('DOMNodeInserted', highlightAgents);
  }
};

// Generic functions

function set_visibility(id, want_visible) {
  if (want_visible != $(id).visible()) { (want_visible) ? $(id).show() : $(id).hide() }
}

function toggle_visibility(/* id1, id2, ...*/) {
  for (var i = 0 ; i < arguments.length ; ++i) {
    var id = arguments[i];
    ($(id).visible()) ? $(id).hide() : $(id).show()
  }
}

function toggle_comment(){
  toggle_visibility('comment_full', 'comment_partial');
  toggle_visibility('comment_up', 'comment_down');
  return false;
}

// For user admin page
function toggleFilter(id) {
  $('options').hide();
  toggle_visibility(id);
  return false;
}

function submitUpload() {
  var filename = $('attachment_content').value.strip();
  if(filename != null && filename.length > 0) {
    $('uploadform').submit();
    $('uploadinput').style.display = "none";
    $('uploadbar').style.display = "block";
  }
}

function notifyOnError(name) {
  alert("Failed to upload file '"+name+"', verify the path");
  resetView();
}

function addAttachment(name, size, id) {
  new Insertion.Bottom("attachmentlist", "<div class='attachment' id='attachment_"+id+"'>"+name+" <span class='size'>"+size+"</span> <a href='#' onclick='deleteAttachment("+id+");return false'>x</a>");
  resetView();
}

function deleteAttachment(id) {
  new Ajax.Updater({success:'attachmentDeleted('+id+')'}, '/attachment/delete/'+id, { asynchronous:true, evalScripts:true});
}

function attachmentDeleted(id) {
  Element.remove('attachment_'+id);
}

var attachmentLists = new Array();

function registerAttachmentList(listId, size) {
  attachmentLists[listId] = size;
}

function deleteFromAttachmentList(listId, itemId) {
  Element.remove($(itemId));
  attachmentLists[listId] = attachmentLists[listId]-1;
  if(attachmentLists[listId] <= 0) {
     Element.remove($(listId));
     delete attachmentLists[listId];
  }
}

function resetView() {
  $('attachment_content').value = '';
  $('uploadbar').style.display = "none";
  $('uploadinput').style.display = "block";
}

function showFlash(flash) {
  $('flash_messages').innerHTML = flash;
  new Effect.Highlight('flash_messages', { duration: 2 });
}

// **** Upload photo stuff
function pictureDeleted(key) {
  $('cancel-block-'+key).hide();
  if (key == 'header_logo') { $('website_url').hide(); }
  selectPicture(key);
}

function selectPicture(key) {
  $('image-block-'+key).hide();
  $('upload-block-'+key).show();
  $('ignore-upload-'+key).value = 0;
}

function resetPicture(key) {
  $('upload-block-'+key).hide();
  $('image-block-'+key).show();
  $('ignore-upload-'+key).value = 1;
}


function checkTicketDelete() {
  if ($F('submit_type') == 'delete')
    alert('Warning - selecting this option will delete the ticket when you click submit. Deleted tickets cannot be recovered.');
}

function check_ticket(ticket_id) {

  if (!$('comment_type') && $F('ticket_requester_name') == '') {
    if (!confirm('You haven\'t entered a requester for the ticket. Submitting this form will register you as the requester.'))
      return false;
  }

  // show alert if we're solving with a public comment, a problem that has associated tickets
  //if ($('associated_incidents_warning') && $F('ticket_status_id') == '3' && isAddingPublicComment() && isUpdatingTicket()) {
  //  if (!confirm($('associated_incidents_warning').innerHTML))
  //    return false;
  //}

  $('submit-button').value = 'Submitting...';
  $('submit-button').disabled = true;

  if (typeof(collaboratorList) != 'undefined')
    collaboratorList.update();

  // Remove requester/cc if it is not visible - so we don't need to update it in the ticket model
  if ($F('submit_type') != 'merge' && $('edit_requester').style.display == 'none')
    $('edit_requester').remove()

  return true
}

function isUpdatingTicket() {
  return $F('submit_type') == '' || $F('submit_type') == 'macro' || $F('submit_type') == 'entry'
}

function isAddingPublicComment() {
  return !$F('comment_value').blank() && $('comment_is_public').checked;
}

function copySubmitType() {
  $('ticket-chat').submit_type.value = $('submit_form').submit_type.value;
}

function submitTicketForm(ticket_id) {
  if (check_ticket()) {
    copySubmitType();
    if ($F('submit_type') == 'merge') {
      showMergeWizard(ticket_id);
    } else {
      if(typeof(ticketTagField) != 'undefined') {
        ticketTagField.beforeFormSubmit();
      }
      $('ticket-chat').submit();
    }
  }
}

function submitBulkUpdateForm() {
  if (fetch_tickets_to_bulk_update()) {
    if ($F('submit_type') == 'merge') {
      showMergeWizard($('tickets_to_bulk_update').value);
    } else {
      if ($('ticket_ticket_type_id') && $('ticket_ticket_type_id').value != "4") {
        $('ticket_date').remove(); // Remove due date if the ticket is not a task
      }
      $('ticket-chat').submit();
    }
  }
}

function showMergeWizard(ticket_id) {
  var unchecked = '';
  if ($$('input.tickets_to_bulk_update')) {
    unchecked = $$('input.tickets_to_bulk_update').collect(function(s) { if (!s.checked) return s.value;}).compact().join(',');
  }
  Lightview.show({
    href: '/merge/new',
    rel: 'ajax',
    options: {
      topclose: true,
      autosize: true,
      backgroundColor: '#999',
      ajax: {
        parameters: { source_ids: ticket_id, unchecked: unchecked },
        method: 'get'
      }
    }
  });
}

function submitSelectedMerge() {
  var nice_id = $('target_id').value.strip();
  if (!nice_id) {
    alert('Please enter a ticket ID');
    return;
  }

  Lightview.show({
    href: '/merge',
    rel: 'ajax',
    options: {
      topclose: true,
      autosize: true,
      backgroundColor: '#999',
      ajax: {
        parameters: Form.serialize('merge_form'), // the parameters from the form
        method: 'get'
      }
    }
  });

}

function submitNewUserFromTicket(addedAs) {
  new Ajax.Request('/people/users/find_or_create.json', {
    method: 'post',
    parameters: Form.serialize('new_user_form'),
    onSuccess : function(response) {
      addUserToTicket(response.responseJSON, addedAs);
    },
    onFailure : function(response) {
      $('user_email').focus();
      new Effect.Highlight('user_email', { duration: 3 });
    }
  });
}

function addUserToTicket(data, addedAs) {
  value = data.email_address_with_name_without_quotes;
  if (addedAs == 'requester') {
    $('ticket_requester_name').value = value;
  } else {
    collaboratorsInput.addEntry(data.id, value);
  }
  Lightview.hide();
}

function observeMergeWizardEvents() {
  document.observe('lightview:hidden', function(event) {
    $('submit-button').value = 'Submit';
    $('submit-button').disabled = false;
  });

  document.observe('lightview:opened', function(event) {
    // Check if we're in step2 first and if the user wrote something as a comment
    if ($('target_comment') && $('comment_value').value.length > 0) {
      // Add current text in comment area as last comment in target ticket
      $('target_comment').value = $('target_comment').value + '\n\nComment during merge: ' + $('comment_value').value;
      $('source_comment').value = $('source_comment').value + '\n\nComment during merge: ' + $('comment_value').value;
    }
  });
}

function copySolvedState() {
  if ( $('submit_form').solved_true ) {
    $('ticketform').ticket_force_status_change.value = $('submit_form').solved_true.checked;
  }
}

function submitRequestForm() {
  $('ticketform').submit();
}

function toggleAttachForm() {
  $('uploads_link').toggleClassName('unfolded');
  $('uploads_field').toggleClassName('unfolded');
}

function submitAttachForm(uploading_msg) {
  if ($('uploads_attribute')) {
    $('token').value = $('uploads_attribute').value;
  }
  $('submit-button').value = uploading_msg;
  $('submit-button').disabled = true;
  document.attach_form.submit();
  $('uploads_form').hide();
  $('uploading_message').removeClassName('display_none');
  document.attach_form.reset();
}

// TODO use prototype instead
function set_selected_for_select(select, selected_value) {
  if (select) {
    for (var i=0; i<select.options.length; i++) {
      select.options[i].selected = (select.options[i].value == selected_value);
    }
  }
}

// Autotagging for ticket
function autotag_ticket(element) {
  if(!$F(element).blank() && ticketTagField && ticketTagField.selectedEntries().length == 0) {
    new Ajax.Request('/tags/autotag', {
      parameters: { text: $F(element), target: 'ticketTagField' }
    });
  }
}

// ***** Prototip tips

function comment_tip(element, title, body) {
  return new Tip(element, ' ' + body, {
    title: title,
    style: 'zd_comment',
    delay: 0,
    border: 4,
    radius: 4,
    width: 600,
    viewport: true,
    hook: { tip: 'topLeft', mouse: true },
    offset: { x: 12, y: 8 }
  });
}

// *****

function stv(value, title, tagger_id, evt, this_elm) {
  if ($('ticket_fields_' + tagger_id)) {
    $('ticket_fields_' + tagger_id).value = value;
    $('title-tagger-' + tagger_id).innerHTML = title.split("").reverse().join("").truncate(26).split("").reverse().join("");
    var e=(evt)?evt:window.event;
    Event.stop(e);
    var li = e.findElement();
    selection_feedback(li);

    return(false);
  }
}

// ***** Macro stuff

function apply_macro(case_id, evt) {
  if (case_id != '') {
    if (typeof(ticket_id) == 'undefined') { 
      this_id = '0';
    } else {
      this_id = ticket_id;
    }

    new Ajax.Updater('case', '/rules/apply_macro/' + case_id + '?ticket_id=' + this_id, { asynchronous: true, evalScripts: true, insertion: Insertion.After, 
        onComplete: function() { $('comment_value').focus(); }, parameters: Form.serialize('ticket-chat') });
    $('case').hide();
    var e = (evt) ? evt: window.event;
    Event.stop(e);
    var li = e.findElement();
    selection_feedback(li);
    return (false);
  }
}

var hide_macro_li = function(li) {
  // using element storage to retrieve the currently open li and close it
  var current_selection = li.up().retrieve('selection');
  if (current_selection) {
    category_set(current_selection, 'none', 0, 'static');
  }
};

// ***** Topic stuff...

var TopicForm = {
  editNewTitle: function(txtField) {
    $('new_topic').innerHTML = (txtField.value.length > 5) ? txtField.value : 'New Topic';
  }
}

var LoginForm = {
  checkLogin: function(txt) {
    if(txt.value.match(/^https?:\/\//)) {
      $('password_fields').hide();
    } else {
      $('password_fields').show();
    }
  }
}

function showOrHideBulkForm() {
  fetch_tickets_to_bulk_update();
  if ($F('tickets_to_bulk_update').blank()) {
    $('bulk-update').hide();
  }
  else {
    $('bulk-update').show();
  }
}

function fetch_tickets_to_bulk_update() {
  $('tickets_to_bulk_update').value = $$('input.tickets_to_bulk_update').collect(function(s) { if (s.checked) return s.value;}).compact().join(',')
  return true;
}

function select_all_tickets_for_bulk_update(elm) {
  state = elm.checked
  if ($('bulk-update')) {
    state ? $('bulk-update').show() : $('bulk-update').hide()
    $$('input.tickets_to_bulk_update').each(function(s) {s.checked = state})
  }
}

// Color picking and calculations for account
var rgb_css_to_hex = function(str) { // e.g. rgb(0, 122, 255)
  var color_components = str.match(/\d+/g);
  var hex_color = '#';
  str.match(/\d+/g).each(function(val){
    hex_color += Number(val).toColorPart();
  });
  return(hex_color);
}

function hsv2hex(hsv_new) {
  rgb = YAHOO.util.Color.hsv2rgb(hsv_new[0], hsv_new[1], hsv_new[2])
  return YAHOO.util.Color.rgb2hex(rgb[0], rgb[1], rgb[2])
}

function calculateColors(){
  var color;
  if (fncIsValidColor(color = $F('branding_header_color')) &&
  fncIsValidColor($F('branding_page_background_color')) &&
  fncIsValidColor($F('branding_sidebox_color'))){
    rgb = YAHOO.util.Color.hex2rgb(color)
    if (!YAHOO.util.Color.isValidRGB(rgb)) return;
    hsv = YAHOO.util.Color.rgb2hsv(rgb[0], rgb[1], rgb[2])
    hsv_new = hsv[0] * 1.03
    if (hsv_new > 1.0) hsv_new = 1.0
    $('branding_tab_background_color').value = hsv2hex([hsv_new, hsv[1] * 0.87, hsv[2] * 0.83])
    hsv_new = hsv[2] * 1.02
    if (hsv_new > 1.0) hsv_new = 1.0
    $('branding_tab_hover_color').value = hsv2hex([hsv[0], hsv[1] * 0.62, hsv_new])
    if ($('branding_tab_hover_color').value == 'FFFFFF')
      $('branding_tab_hover_color').value = 'E8E8E8'
    $('branding_text_color').value = (hsv[2] > 0.85) ? "2A2A2A" : "FFFFFF";
    return true;}
  else {
    alert('You have not entered a valid hex color');
    return false;
  }
}

function fncIsValidColor(hexcolor) {
  var strPattern = /^#?[0-9a-f]{3,6}$/i;
  return strPattern.test(hexcolor);
}

// ********* Sorting
Ordering = {
  SetOrder: function(table){
    Element.hide(table);
    Element.show(table + '_sort');
  },

  cancelOrdering: function(listOfItems) {
    var sortableList = $j(listOfItems + "_sort");
    $j(listOfItems).show();

    sortableList.hide();
    var sortByOriginalPosition = function(a, b) {
      var attrName = "data-zendesk-original-position";
      return ($j(a).attr(attrName) < $j(b).attr(attrName)) ? -1 : ($j(a).attr(attrName) > $j(b).attr(attrName)) ? 1 : 0;
    }

    var sortedRules = $j("ul li.item.sortable", sortableList).sort(function(a, b) {
      return sortByOriginalPosition(a, b);
    });
    $j("ul li.item.sortable", sortableList).remove();
    $j("ul", sortableList).prepend(sortedRules);
  }
};


// Cookie stuff

var Cookie = {
  set: function(name, value, daysToExpire) {
    var expire = '';
    if (daysToExpire != undefined) {
      var d = new Date();
      d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));
      expire = '; expires=' + d.toGMTString();
    }
    return (document.cookie = escape(name) + '=' + escape(value || '') + expire + '; path=/');
  },
  get: function(name) {
    var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)'));
    return (cookie ? unescape(cookie[2]) : null);
  },
  erase: function(name) {
    var cookie = Cookie.get(name) || true;
    Cookie.set(name, '', -1);
    return cookie;
  },
  accept: function() {
    if (typeof navigator.cookieEnabled == 'boolean') {
      return navigator.cookieEnabled;
    }
    Cookie.set('_test', '1');
    return (Cookie.erase('_test') === '1');
  }
};

/* Textarea auto-resize. http://www.felgall.com/jstip45.htm */
function textarea_resize() {
  t = this;
  a = t.value.split('\n');
  b=1;
  for (x=0;x < a.length; x++) {
    if (a[x].length >= t.cols) b+= Math.floor(a[x].length/t.cols);
  }
  b += a.length;
  if (b > t.rows) t.rows = b;
}

//Javacript difference in time in words - http://nullstyle.com/2007/06/02/caching-time_ago_in_words/
function time_ago_in_words(from) {
  return distance_of_time_in_words(new Date(), new Date(from))
}

function i18n_time_ago_in_words(from) {
  return i18n_distance_of_time_in_words(new Date(), new Date(from))
}

function distance_of_time_in_words(to, from) {
  seconds_ago = ((to  - from) / 1000);
  minutes_ago = Math.floor(seconds_ago / 60)

  if(minutes_ago <= 0) { return "less than a minute";}
  if(minutes_ago == 1) { return "a minute";}
  if(minutes_ago < 45) { return minutes_ago + " minutes";}
  if(minutes_ago < 90) { return "1 hour";}
  hours_ago  = Math.round(minutes_ago / 60);
  if(minutes_ago < 1439) { return hours_ago + " hours";}
  if(minutes_ago < 2879) { return "1 day";}
  days_ago  = Math.round(minutes_ago / 1440);
  if(minutes_ago < 43199) { return days_ago + " days";}
  if(minutes_ago < 86399) { return "1 month";}
  months_ago  = Math.round(minutes_ago / 43200);
  if(minutes_ago < 525960) { return months_ago + " months";}
  if(minutes_ago < 1051920) { return "1 year";}
  years_ago  = Math.round(minutes_ago / 525960);
  return "over " + years_ago + " years"
}

/*
  Object factory. Used to allow multiple occurences of the same object type on the same page
  Use like so:

  ObjectFactory.create(TextWidget, {
    id: <%= @widget.id %>, params: <%= @widget.params.to_json %>
  });

  This instantiates and returns a new instance of the class specified. The instance gets initialized
  with an args parameter, containing the property list (eg. { id: 4, params: 'horse' }). The id must be
  set as it is used to lookup the instance later. So, to get the instance reference:

  ObjectFactory.get(<%= @widget.id%>).dance_the_funky_chicken_dance();
*/
var ObjectFactory       = Class.create({});
ObjectFactory.instances = new Hash();

ObjectFactory.create    = function(type, args) {
  instance = new type(args);
  ObjectFactory.instances.set(args.id, instance);
  return instance;
};

ObjectFactory.get = function(id) {
  return ObjectFactory.instances.get(id);
};

ObjectFactory.remove = function(id) {
  return ObjectFactory.instances.unset(id);
};

var usableChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz";

function randomString() {
  var result = '';

  for (var i=0; i< 48; i++) {
    var index = Math.floor(Math.random() * usableChars.length);
    result += usableChars.substring(index, index+1);
  }

  return result;
}

document.getUrlParameter = function(name) {
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
  var results = regex.exec(window.location.href);
  return results ? unescape(results[1]) : null;
}


// Will format strings in human readable format... addCommas(1234567890) -> 1,234,567,890
function addCommas(nStr)
{
  nStr += '';
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(nStr)) {
    nStr = nStr.replace(rgx, '$1' + ',' + '$2');
  }
  return nStr;
}

function showSortingForForumType(type_id) {
  set_visibility("div_ordering", (type_id == 1 ? true : false))
}

var AccountAlert = {
  hide: function(id, key) {
    var notice = $j('#account_alert_' + id);
    $j.cookie(key, '1', 14);
    notice.hide();
  },

  show: function(id, key) {
    if (!$j.cookie(key)) {
      var notice = $j('#account_alert_' + id);
      notice.show();
    }
  }
}
