/*
 * $RCSfile$
 * $Revision: 30626 $
 * $Date: 2006-05-30 09:55:32 -0700 (Tue, 30 May 2006) $
 *
 * Copyright (C) 1999-2008 Jive Software. All rights reserved.
 *
 * This software is the proprietary information of Jive Software. Use is subject to license terms.
 */

/*
 * Javascript for tag input UI. These functions are used on the document create / edit page,
 the forum message create / edit page and the blog post create / edit page.
 */
function customSelector(instance) {
  var matches   = {};
  var ret       = []; // Beginning matches
  var partial   = []; // Inside matches
  var entry     = instance.getToken();
  var count     = 0;
  var existingTags = $('jive-tags').value.split(/\s|,/g);


  for (t in instance.options.array) {
    var elem = t;
    var foundPos = elem.toLowerCase().indexOf(entry.toLowerCase());
    while (foundPos != -1) {
      if (foundPos == 0 && elem.length != entry.length && !existingTags.include(t)) {
        matches[t] = "<li>" + t + "<span class='informal'> (" + instance.options.array[t] + ")</span></li>";
        ret.push(t)
        break;
      }
      foundPos = elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1);
    }
  }

  // sort the tag suggestions first by usage then alphabetically
  ret.sort(function (a,b) {
        if (instance.options.array[b] - instance.options.array[a] == 0) {
            return (b > a ? -1 : 1);
        } else {
            return instance.options.array[b]-instance.options.array[a]
        }
    });

  var dropDown = '';
  for (i=0; i<ret.length; i++) {
    dropDown += matches[ret[i]];
  }
  return "<ul>" + dropDown + "</ul>";
}

function customOnShow(element, update) {
    s = update;
    s.style.overflow = 'visible'
    s.style.height = 'auto';
    s.style.width = 'auto';

    // create a div to get the actual height of the now invisible suggestions div
    inviso = document.createElement('div')
    inviso.style.top = inviso.style.left = 0
    inviso.style.position = 'absolute'; inviso.style.visibility = 'hidden'
    inviso.innerHTML = update.innerHTML;
    $('jive-tags').parentNode.appendChild(inviso)

    var autoCompleteHeight = getY($('jive-tag-choices-container')) + inviso.offsetHeight
    // suggestions div too big for the current window? shrink it to 240px and show scrollbars
    if(windowHeight() < autoCompleteHeight) {
        // editors note: it sure would be nice to be able to resize the height of thesuggestions
        // div to the number of pixels left after the jive-tag-choices-container in the document...
        // Unfortunately it's not possible to reliably measure the size of the body element,
        // for more info see: http://www.quirksmode.org/js/doctypes.html
        s.style.height = '240px'
        s.style.overflow = 'auto'
		s.scrollTop = 0
		if(inviso.clientWidth < inviso.scrollWidth) {
            s.style.width = inviso.scrollWidth + (inviso.scrollWidth - inviso.clientWidth) + 'px' // get rid of horizontal scrollbars on ie overflow divs
        }
	}

    // create a div to calc the current width of the words in the tags input box
    inviso = document.createElement('div')
	inviso.style.top = inviso.style.left = 0
	inviso.style.position = 'absolute'; inviso.style.visibility = 'hidden'
    inviso.style.fontSize =  Element.getStyle(element, 'font-size');
	inviso.style.fontFamily = Element.getStyle(element, 'font-family');
    var text = element.value;
	var esc = {'<':'[','>':']',' ':'&nbsp;'}
	for(var i in esc) {
		text=text.replace(new RegExp(i,'g'), esc[i])
	}
	inviso.innerHTML = text
    $('jive-tags').parentNode.appendChild(inviso)
    n = inviso.offsetWidth - 10;

    s.style.left = getX(element) + n + 'px' // put dropdown right below current typed tag

    if(getX(s) + s.offsetWidth > getX(element) + element.offsetWidth) { // force dropdown to right align to tags input
		s.style.left = getX(s) - (getX(s) + s.offsetWidth - getX(element) - element.offsetWidth) + 'px'
	}

    // check for IE7 which for some reason reports the 'x' position of S as something like 28604108
    if (getX(s) > 10000) {
        s.style.left = '24px';
    }

    Effect.Appear(update,{duration:0.15});
    localOnShow();
}

function customOnHide(element, update){
    new Effect.Fade(update,{duration:0.15});
    localOnHide();
}

function processKey(set) {
    var setArray = set.value.split(/\s/i);

    // remove all selected tags
    var elems = $$('.jive-tag-selected');
    for(var i=0;i<elems.length;i++) {
        elems[i].removeClassName('jive-tag-selected');
        elems[i].addClassName('jive-tag-unselected');
    }
    // add appropriate selected tags
    for(i=0;i<setArray.length;i++) {
        elems = $$('.jive-tag-unselected');
        for (var j=0;j<elems.length;j++) {
            if (elems[j].firstChild && elems[j].firstChild.nodeValue == setArray[i]) {
                elems[j].removeClassName('jive-tag-unselected');
                elems[j].addClassName('jive-tag-selected');
            }
        }
    }

    updateTagSets();
}

function swapTag(tag) {
    var currentValue = $F('jive-tags');

    var elems;
    if (!(tag instanceof String)) {
        elems = new Array($(tag));
        tag = tag.firstChild.nodeValue;
    }
    else {
        elems = $$('.jive-tagname-' + tag);
    }

    // change the value of the tags text field accordingly (only do this once)
    if (elems.length > 0) {
        if (elems[0].hasClassName('jive-tag-selected')) {
            var setArray = currentValue.split(/\s/i);
            var val = '';
            for (var j=0; j<setArray.length;j++) {
                if (setArray[j].length > 0 && setArray[j] != ' ' && setArray[j].toLowerCase() != tag.toLowerCase()) {
                    val += setArray[j] + ' ';
                }
            }
            $('jive-tags').value = val;
        } else {
            if (currentValue.length == 0 || currentValue.charAt(currentValue.length - 1) == ' ') {
                $('jive-tags').value = $F('jive-tags') + tag;
            } else {
                $('jive-tags').value = $F('jive-tags') + ' ' + tag;
            }
        }

        // update the classes for all instances of this tag link
        for (var i=0;i<elems.length;i++) {
            if (elems[i].hasClassName('jive-tag-selected')) {
                elems[i].removeClassName('jive-tag-selected');
                elems[i].addClassName('jive-tag-unselected');
            } else {
                elems[i].removeClassName('jive-tag-unselected');
                elems[i].addClassName('jive-tag-selected');
            }
        }

        updateTagSets();
    }
}

function updateTagSets() {
    if ($('jive-taggroups-active-container')) {
        var tagSetNames = new Array();
        var index = 0;

        // get all tags that are selected
        var tagArray = $$('.jive-tag-selected');
        for(var i=0;i<tagArray.length;i++) {
            var tagSetName = tagArray[i].name;
            if (tagSetName != 'populartag') {
                if (tagSetNames.indexOf(tagSetName) == -1) {
                    tagSetNames[index++] = tagSetName;
                }
            }
        }
        if (tagSetNames.length > 0) {
            $('jive-taggroups-active-container').style.display = '';
            $('jive-taggroups-active').innerHTML = tagSetNames.join(", ");
        } else {
            $('jive-taggroups-active').innerHTML = "";
            $('jive-taggroups-active-container').style.display = 'none';
        }
    }
}

function swapTagSet(tagSetID) {
    // hide the currently displayed tag set
    var elems = $$("#jive-taggroups-container div");
    for (var i=0;i<elems.length;i++) {
        elems[i].style.display = 'none';
    }

    if (tagSetID) {
        $('jive-taggroup-'+tagSetID).style.display = "";
    }
}

// get window size
function windowHeight() { return self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || 0 }
function windowWidth() { return self.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || 0 }

// get pixel position of an object
function getY(o){ var y = 0
	if (o.offsetParent) while (o.offsetParent) { y += o.offsetTop; o = o.offsetParent }
	return y
}
function getX(o){ var x = 0
	if (o.offsetParent) while (o.offsetParent) { x += o.offsetLeft; o = o.offsetParent }
	return x
}

function keydown(e) { e=e||window.event
	if(Element.visible('jive-tag-choices')) {
		switch(e.keyCode) {
			case 40:
				scrollDropdown()
				prevent(e)
				break
			case 38:
				scrollDropdown()
				prevent(e)
				break
        }
    }
}

function prevent(e) {
	if (window.event) window.event.returnValue = false
	else e.preventDefault()
}

function scrollDropdown() {
    var amt = Math.ceil((Math.ceil($('jive-tag-choices').offsetHeight - tagHeight) / tagHeight) / 2 )
    var scrollTo = (ac.index * tagHeight) - (amt * tagHeight)
    $('jive-tag-choices').scrollTop = (scrollTo < 0) ? 0 : scrollTo
}

//hooks for views that need to do something on show and on hide
function localOnShow(){}
function localOnHide(){}

var ac = new Autocompleter.Local('jive-tags',
    'jive-tag-choices',
    Community.feed,
    {tokens: [' ', ','], selector: customSelector, onShow: customOnShow, onHide: customOnHide});

$('jive-tags').onkeydown = keydown;
var tagHeight = $('jive-tags').offsetHeight;

updateTagSets();

