function tagFace(objectID, tog, togClose, remove) { /* null tagFace( str objectID, str tag, str tag closure [, bool tag is removable] )*/
//a tog is a tag made by me lolz.
var texta = new Object;
texta = document.getElementById(objectID);
var tag = tog;
var tagClose = togClose;

var startPos = texta.selectionStart;
var   endPos = texta.selectionEnd;

//selection divides the whole in 3 parts.
var s1 = texta.value.substring(0, startPos);
var s2 = texta.value.substring(startPos, endPos);
var s3 = texta.value.substring(endPos, texta.value.length);

//---si el tag está ya abierto, no lo abre de nuevo.
if(s1.lastIndexOf(tog) > s1.lastIndexOf(togClose))
  tag = '';
//---

//---si el tag cierra delante de selección y antes de otras aperturas, no cerrarlo.
if(s3.indexOf(togClose) >= 0 )
  if(s3.indexOf(togClose) < s3.indexOf(tog) || s3.indexOf(tog) < 0)
    tagClose = '';
//---

  //---string selecccionado se limpia de apariciones del tag,
 //---puesto que todo él ha sido señalado como taggeado.
//---se cuentan los caracteres borrados para no alargar la post-selección.
var erased = 0;
     while(s2.indexOf(tog)>=0) { s2 = s2.replace(tog,      ""); erased+=tog.length; }
while(s2.indexOf(togClose)>=0) { s2 = s2.replace(togClose, ""); erased+=togClose.length; }
//---


//---si el tag es BOLD, ITALIC o UNDERLINE, debe permitir 'remove'
//---en caso de que la selección esté exacatmente entre tags
  /*
   por ahora funciona sólo si el string está
   exactamente encapsulado por el tag.
   debería cambiarse a otro que lo quite así
   no sea el exactamente contenedor del string
   seleccionado.
  */
  if(remove && s1.lastIndexOf(tog) == (s1.length - (tog.length)) && s3.indexOf(togClose) == 0) {
    s1 = s1.substring(0, (s1.length - tog.length));
    s3 = s3.substring(togClose.length, s3.length);
    startPos += (-1) * tog.length;
    endPos += (-1) * tog.length;
    }
//---

texta.value = s1 +tag+ s2 +tagClose+ s3;

/*
 la selección queda hecha sobre lo que antes era s2.
 ambas se corren 'tag' a la derecha y el final erased a la izquierda,
 pues s2 pudo haberse reducido de tamaño.
 */
  texta.selectionEnd =  endPos  + tag.length - erased;
texta.selectionStart = startPos + tag.length;
texta.focus();
//---
}


var secondTags = new Array;
var t = 0;
function tagVariable(objectID, tag, secondTag, isLink) {
var area = new Object;
area = document.getElementById(objectID);
secondTags[t] = secondTag;
t++;

var startPos = area.selectionStart;
var   endPos = area.selectionEnd;

//selection divides the whole in 3 parts.
var s1 = area.value.substring(0, startPos);
var s2 = area.value.substring(startPos, endPos);
var s3 = area.value.substring(endPos, area.value.length);

var tog = tag; //even if deleted memory of tag is needed afterwards.
var tagClose = tag.substring(0,1)+'/'+tag.substring(1, tag.length);

/*---
 string selecccionado se limpia de apariciones del tag,
 puesto que todo él ha sido señalado como taggeado.
 se cuentan los caracteres borrados para no alargar la post-selección.
 se borran también los secondTags, almacenados en vector global.
 */
var erased = 0;
            while(s2.indexOf(tag)>=0) { s2 = s2.replace(tag,      ""); erased+=tag.length; }
       while(s2.indexOf(tagClose)>=0) { s2 = s2.replace(tagClose, ""); erased+=tagClose.length; }
for(var i=0; i<=t; i++)
  while(s2.indexOf(secondTags[i])>=0) { s2 = s2.replace(secondTags[i], ""); erased+=secondTags[i].length; }
//---

//---si el tag está ya abierto, o si es link y no hay texto seleccionado, no lo abre.
if(s1.lastIndexOf(tag) > s1.lastIndexOf(tagClose) || (isLink && s2=='')) {
  tag = '';
  secondTag = '';
  }
//---

//---si el tag cierra delante de selección y antes de otras aperturas, o si es link y no hay texto seleccionado, no cierra.
if(s3.indexOf(tagClose) >= 0 || (isLink && s2==''))
  if(s3.indexOf(tagClose) < s3.indexOf(tog) || s3.indexOf(tog) < 0 || (isLink && s2==''))
    tagClose = '';
//---

area.value = s1+ tag + secondTag +s2+ tagClose +s3;

area.selectionEnd =  endPos  + tag.length + secondTag.length - erased;
area.selectionStart = startPos + tag.length + secondTag.length;
area.focus();
}



function tagAlign(objectID, align) {
//a tog is a tag made by me lolz.
var area = new Object;
    area = document.getElementById(objectID);

var startPos = area.selectionStart;
var   endPos = area.selectionEnd;

//s1 is 0 to point after the last '\n' before selectionStart.
var s1 = area.value.substring(0, area.value.lastIndexOf('\n', startPos-1)+1);
//only if there are '\n's after endPos does s3 have any content
var s3 = '';
if(area.value.indexOf('\n', endPos)>=0)
  s3 = area.value.substring(area.value.indexOf('\n', endPos), area.value.length);
//s2 is everything between 1 & 3.
var s2 = area.value.substring(s1.length, (area.value.length - s3.length));

/*---
 if the selected opens an alignment, it shall NOT
 be forgotten at the remaining text.
 tag that opens should be passed at closing point if
 the remaining s3 has a closing mark before any opening.
 */
 var pass = false;
 if(s2.indexOf('[ali]')==0 && s3.indexOf('[/ali]')>=0) {
   //closing tag in s3 must precede any opening.
   if(s3.indexOf('[ali]') >= 0) {
     if(s3.indexOf('[/ali]') < s3.indexOf('[ali]')) pass = true;
     }
   else pass = true;
   }

 if(pass) {
   //if s3 starts with '\n's, tag should be put after them.
   var search = 0;
   while(s3.indexOf('\n',search)==0+search) search++;
   s3 = s3.substring(0,search)+'[ali]'+s2.substring(5,8)+s3.substring(search,s3.length);
   }
//---

/*---
 s2, being the tagged chunk, should be cleansed of any old tags.
 if s2 is already tagged, start and end tags will be cleansed
 and right after put back.
 */
 var erased = 0;
 while(s2.indexOf('[ali]')>=0) {
   s2 = s2.replace('[ali]', "");
   erased+=5;
   }
 while(s2.indexOf('[r]')>=0) {
   s2 = s2.replace('[r]', "");
   erased+=3;
   }
 while(s2.indexOf('[c]')>=0) {
   s2 = s2.replace('[c]', "");
   erased+=3;
   }
 while(s2.indexOf('[l]')>=0) {
   s2 = s2.replace('[l]', "");
   erased+=3;
   }
 while(s2.lastIndexOf('[/ali]')>=0) {
   s2 = s2.replace('[/ali]', "");
   erased+=6;
   }
//---

var tagClose = tag.substring(0,1)+'/'+tag.substring(2, tag.length);
area.value = s1+'[ali]'+align+s2+'[/ali]'+s3;
}