var tags=new Array();
var bigImages=new Array();

var searchPath=new SearchPath();

var currentTags=null;
var searchResult=null;
//var searchResultTitle=null;


var searchResultPageSize=10;
//var resultPage=null;

var nlsSearchBack="<< Back";
var nlsSearchNext="Next >>";
var nlsFigures="figures";
var nlsFigure="figure";

//////////////////////////////////////
// SearchPath
//////////////////////////////////////
function SearchPath() {
  this.tagNames=new Array();
  this.tagArrays=new Array();
  this.searchResultArrays=new Array();
}

SearchPath.prototype.add=function (tagName,tags,searchResult) {
  this.tagNames[this.tagNames.length]=tagName;
  this.tagArrays[this.tagArrays.length]=tags;
  this.searchResultArrays[this.searchResultArrays.length]=searchResult;
}

SearchPath.prototype.getTagIndex=function (tagName) {
  for (var i=0; i<this.tagNames.length; i++) {
    if (tagName==this.tagNames[i]) {
      return i;
    }
  }
  return -1;

}

SearchPath.prototype.hasTag=function (tagName) {
  return this.getTagIndex(tagName)>=0;
}

SearchPath.prototype.removeAfter=function(index) {
  this.tagNames.length=index+1;
  this.tagArrays.length=index+1;
  this.searchResultArrays.length=index+1;
}


//////////////////////////////////////
// tag class
//////////////////////////////////////
function Tag(name,category,items) {
  this.name=name;//name.replace(" ","&nbsp;");
  this.category=category;
  this.items=items.split(",");
}

Tag.prototype.add=function addItem(item) {
  this.items[this.items.length]=item
}

Tag.prototype.hasItem=function hasItem(item) {
  for (var i=0; i<this.items.length; i++) {
    if (this.items[i]==item) {
      return true;
    }
  }
  return false;
}

////////////////////////////////////////

function addtag(name, category, items) {
  var t=new Tag(name,category,items);
  tags[tags.length]=t;
}



function addBigImages(items) {
  var a=items.split(",");
  for (var i=0; i<a.length; i++) {
    bigImages[bigImages.length]=a[i];
  }
}

function isBigImage(item) {
  for (var i=0; i<bigImages.length; i++) {
    if (bigImages[i]==item) {
      return true;
    }
  }

  return false;
}

function getItemTags(item) {
  var result=new Array();
  for (var i=0; i<tags.length; i++) {
    var t=tags[i];
    for (var j=0; j<t.items.length; j++) {
      if (t.items[j]==item) {
        result[result.length]=t.name;
      }
    }
  }

  return result;
}

function getTag(tagName) {
  for (var i=0; i<tags.length; i++) {
    if (tagName==tags[i].name) {
      return tags[i];
    }
  }
  return null;
}

function clearSearchResult() {
  var d=document;
  var mainDiv=d.getElementById("search_result");

  while (mainDiv.firstChild!=null) {
    mainDiv.removeChild(mainDiv.firstChild);
  }
}

/*
function showSingleFigure(index, greyscale) {
  searchResult=new Array(1);
  searchResult[0]=index;
  searchResultTitle="figure: "+index;
  showSearchResult(1);
} */

function showFigure(elem, index,greyscale) {
  while (index.length<3) {
    index="0"+index;
  }

  var d=document;

  var elemImageDiv=d.createElement("div");
  elem.appendChild(elemImageDiv);
  elemImageDiv.style.textAlign="center";

  var elemIMG=d.createElement("img");
  elemImageDiv.appendChild(elemIMG);
  if (greyscale) {
    elemIMG.src="../../images/library/grey/g"+index+".gif";
  } else {
    elemIMG.src="../../images/library/bw/f"+index+".gif";
  }

  
  var elemFigDiv=d.createElement("div");
  elemFigDiv.style.textAlign="center";
  elemFigDiv.style.fontWeight="bold";
  elemFigDiv.innerHTML=nlsFigure+": "+index;
  elem.appendChild(elemFigDiv);

  var elemTagsDiv=d.createElement("div");
  elem.appendChild(elemTagsDiv);
  elemTagsDiv.style.textAlign="center";

  showFigureTags(index,elemTagsDiv);
}

function showFigureTags(itemIndex, elem) {
  var d=document;
  var itemTags=getItemTags(itemIndex);

  for (var i=0; i<itemTags.length; i++) {
    if (i>0) {
      var elemComma=d.createTextNode(", ");
      elem.appendChild(elemComma);
    }
    
    var elemA=d.createElement("a");
    elemA.href="javascript:OnFigureTagClick('"+itemTags[i]+"');";
    elemA.title=getTag(itemTags[i]).items.length+" "+nlsFigures;
    elemA.innerHTML=itemTags[i];
    elem.appendChild(elemA);
  }
}

function showAllTags() {
  currentTags=tags;

  searchPath.add("#",tags,new Array());
  showCurrentTags();
}

function showCurrentTags() {
  var d=document;
  var divTags=d.getElementById("all_tags");
  divTags.innerHTML="";

  if (currentTags.length==0) {
    divTags.style.display="none";
  } else {
    divTags.style.display="";
  }

  var tt=reorderAlphabetically(calculateCloudGroups(orderTagsByItemCount(currentTags)));

  for (var i=0; i<tt.length; i++) {
    if (i>0) {
      divTags.appendChild(d.createTextNode(" "));
    }

    var elemTagA=d.createElement("a");
    elemTagA.href="javascript:OnTagClick('"+tt[i].name+"');";
    elemTagA.title=tt[i].items.length+" "+nlsFigures;
    var regexp=/ /g;
    var str=tt[i].name.replace(regexp,"&nbsp;");
    elemTagA.innerHTML=str;
    elemTagA.style.fontSize=10+tt[i].group;

    divTags.appendChild(elemTagA);
  }
}

function OnSearchPathClick(index) {
  searchPath.removeAfter(index);
  searchResult=searchPath.searchResultArrays[index];
  currentTags=searchPath.tagArrays[index];
  showCurrentTags();
  showSearchResult(1);
}

function OnFigureTagClick(tagName) {
  searchPath.removeAfter(0);
  currentTags=tags;
  OnTagClick(tagName);
}

function OnTagClick(tagName) {
  if (searchPath.hasTag(tagName)) {
     OnSearchPathClick(searchPath.getTagIndex(tagName));
  }

  var t=null;
  for (var i=0; i<currentTags.length; i++) {
    if (currentTags[i].name==tagName) {
      t=currentTags[i];
      break;
    }
  }

  
  var newTags=new Array();
  for (var i=0; i<t.items.length; i++) {
    for (var j=0; j<tags.length; j++) {
      if (tags[j].name!=tagName && !searchPath.hasTag(tags[j].name) && tags[j].hasItem(t.items[i])) {
        var flag=false;
        for (var k=0; k<newTags.length; k++) {
          if (newTags[k].name==tags[j].name) {
            newTags[k].add(t.items[i]);
            flag=true;
            break;
          }
        }
        if (!flag) {
          newTags[newTags.length]=new Tag(tags[j].name,"",t.items[i]);
        }
      }
    }
  }

  currentTags=newTags;
  showCurrentTags();

  searchResult=t.items;
  //searchResultTitle="tag: "+tagName;

  searchPath.add(tagName,currentTags,searchResult);

  showSearchResult(1);
}

function showSearchPathTitle(elem) {
  if (searchPath.tagNames.length==1) {
    return;
  }

  var d=document;
  for (var i=0; i<searchPath.tagNames.length; i++) {
    var a=d.createElement("a");
    a.href="javascript:OnSearchPathClick("+i+")";
    a.innerHTML=searchPath.tagNames[i];
    elem.appendChild(a);

    if (i<searchPath.tagNames.length-1) {
      elem.appendChild(d.createTextNode(" / "));
    }
  }
}

function showSearchResult(pageNumber) {
  clearSearchResult();

  window.scrollTo(0,0);

  var d=document;
  var mainDiv=d.getElementById("search_result");

  var elemTitle=d.createElement("h2");
  elemTitle.style.textAlign="center";
  showSearchPathTitle(elemTitle);
  //elemTitle.innerHTML=searchResultTitle;
  //elemTitle.appendChild(d.createTextNode(searchResultTitle));
  mainDiv.appendChild(elemTitle);

  var elemNavTop=d.createElement("div");
  elemNavTop.style.textAlign="center";
  mainDiv.appendChild(elemNavTop);
  showSearchPages(elemNavTop,pageNumber);

  var elemTable=d.createElement("table");
  elemTable.width="100%";
  mainDiv.appendChild(elemTable);

  var elemTBody=d.createElement("tbody");
  elemTable.appendChild(elemTBody);    

  var startIndex=(pageNumber-1)*searchResultPageSize;

  var elemTR=null;
  for (var i=0; i<searchResultPageSize; i++) {
    var currentIndex=startIndex+i;
    if (currentIndex<searchResult.length) {
      if (elemTR==null) {
        elemTR=d.createElement("tr");
        elemTBody.appendChild(elemTR);
      }
      
      var elemTD=d.createElement("td");
      elemTR.appendChild(elemTD);

      if ((currentIndex==searchResult.length-1 && elemTR.childNodes.length==1) ||
          (isBigImage(searchResult[currentIndex])) ||
          (currentIndex<searchResult.length-1 && isBigImage(searchResult[currentIndex+1]) && elemTR.childNodes.length==1)) {
        elemTD.colSpan=2;
        elemTR=null;
      } else if (elemTR.childNodes.length==2) {
        elemTR=null;
      }

      showFigure(elemTD,searchResult[currentIndex],true);
    } else {
      break;
    }
  }

  var elemNavBottom=d.createElement("div");
  elemNavBottom.style.textAlign="center";
  mainDiv.appendChild(elemNavBottom);
  showSearchPages(elemNavBottom,pageNumber);
}

function showSearchPages(elem, pageNumber) {
  if (searchResult.length<=searchResultPageSize) {
    return;
  }

  var d=document;

  var elemBackText=d.createTextNode(nlsSearchBack);
  if (pageNumber==1) {
    elem.appendChild(elemBackText);
  } else {
    var elemBackA=d.createElement("a");
    elemBackA.appendChild(elemBackText);
    elem.appendChild(elemBackA);
    elemBackA.href="javascript:showSearchResult("+(pageNumber-1)+");";
  }

  var lastPageNumber=Math.floor(searchResult.length/searchResultPageSize);
  if (searchResult.length % searchResultPageSize > 0) {
    lastPageNumber++;
  }

  for (var i=1; i<=lastPageNumber; i++) {
    if (i>0) {
      elem.appendChild(d.createTextNode(" "));
    }

    var elemText=d.createTextNode(i);
    if (i==pageNumber) {
      var elemB=d.createElement("b");
      elemB.appendChild(elemText);
      elem.appendChild(elemB);
    } else {
      var elemA=d.createElement("a");
      elemA.appendChild(elemText);
      elemA.href="javascript:showSearchResult("+i+");";
      elem.appendChild(elemA);
    }
  }

  elem.appendChild(d.createTextNode(" "));

  var elemNextText=d.createTextNode(nlsSearchNext);
  if (pageNumber==lastPageNumber) {
    elem.appendChild(elemNextText);
  } else {
    var elemNextA=d.createElement("a");
    elemNextA.appendChild(elemNextText);
    elem.appendChild(elemNextA);
    elemNextA.href="javascript:showSearchResult("+(pageNumber+1)+");";
  }
}

function compareByItemCount(a,b) {
  var result=b.items.length-a.items.length;
  if (result==0) {
    var c1=a.name.charAt(0);
    var c2=b.name.charAt(0);

    if (c1<c2) {
      return -1;
    } else if (c1>c2) {
      return 1;
    } else {
      return 0;
    }
  } else {
    return result;
  }
}

function orderTagsByItemCount(tagArray) {
  return tagArray.sort(compareByItemCount);
}

function calculateCloudGroups(tagArray) {
  var maxGroup=20;
  var group=0;
  var lastGroupValue=-1;

  for (var i=0; i<tagArray.length; i++) {
    var groupValue=Math.floor(tagArray[i].items.length/2);
    if (groupValue!=lastGroupValue && group<maxGroup) {
      group++;
    }
    tagArray[i].group=maxGroup+1-group;
    lastGroupValue=groupValue;
  }

  if (group==1) {
    for (var i=0; i<tagArray.length; i++) {
      tagArray[i].group=Math.floor(maxGroup/2);
    }
  } else if (group<20) {
    for (var i=0; i<tagArray.length; i++) {
      tagArray[i].group=maxGroup+Math.floor((tagArray[i].group-maxGroup)*maxGroup/group);
    }
  }

  return tagArray;
}

function reorderToCloud(tagArray) {
  var result=new Array(tagArray.length);

  var maxGroup=20;
  var group=0;
  var lastGroupValue=0;

  var startIndex=0;
  var endIndex=0;
  for (var i=0; i<tagArray.length; i++) {
    var groupValue=Math.floor(tagArray[i].items.length/2);
    if (groupValue!=lastGroupValue && group<maxGroup) {
      group++;
    }
    tagArray[i].group=21-group;
    lastGroupValue=groupValue;

    //find start empty section;
    for (var j=startIndex; j<result.length; j++) {
      if (result[j]==null) {
        startIndex=j;
        break;
      }
    }

    endIndex=result.length;
    for (var j=startIndex+1; j<result.length; j++) {
      if (result[j]!=null) {
        endIndex=j;
        break;
      }
    }

    result[startIndex+Math.floor((endIndex-startIndex)/2)]=tagArray[i];

    startIndex=endIndex;
    if (startIndex>=result.length) {
      startIndex=0;
    }
  }

  return result;
}

function compareByName(a,b) {
  var name1=a.name.toUpperCase();
  var name2=b.name.toUpperCase();
  if (name1<name2) {
    return -1;
  } else if (name1>name2) {
    return 1
  } else {
    return 0;
  }
}

function reorderAlphabetically(arr) {
  return arr.sort(compareByName);
}

function renameTag(oldName,newName) {
  for (var i=0; i<tags.length; i++) {
    if (tags[i].name==oldName) {
      tags[i].name=newName;
    }
  }
}

