var tagCountMax = 6;
var tagCount = 0;

var colorCountMax = 4;
var colorCount = 0;

var criteriaCountMax = 8;
var criteriaCount = 0;

var activeInput = null;
var selector = null;

function log(message) {
  if (message == null) return;
  message = message.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/&/g, "&amp;")
  var log = document.getElementById("log");
  if (!log) return;
  var div = document.createElement("div");
  div.innerHTML = message.toString();
  log.appendChild(div);
}

function setActiveInput(ai) {
  activeInput = ai;
  //TODO generalize image specific test
  if (activeInput && activeInput.id.indexOf("color-") == 0 && selector) {
    selector.setValue(activeInput.value);
  }
}

function getActiveIndex() {
  if (!activeInput) return -1;
  var id = activeInput.id;
  var parts = id.split("-");
  var i = parseInt(parts[2]);
  return i;
}

function updateButtons() {
  var mayAddTags = tagCount != tagCountMax && criteriaCount != criteriaCountMax;
  var mayAddColor = colorCount != colorCountMax && criteriaCount != criteriaCountMax;
  var maySearch = criteriaCount != 0;
  document.getElementById("add-color-button").disabled = !mayAddColor;
  document.getElementById("add-tags-button").disabled = !mayAddTags;
  document.getElementById("search-button").disabled = !maySearch;
  document.getElementById("explanation-row").style.display = maySearch ? "none" : "";
}

function updateAddStatus() {
  var addTr = document.getElementById("add-color-row");
  if (colorCount == colorCountMax) {
    addTr.style.display="none";
  } else {
    addTr.style.display="";
  }

  var enabled = true;
  for(var i = 0; i < colorCount; i++) {
    if (!document.getElementById("color-input-"+i).value) {
      enabled = false;
      break;
    }
  }
  var addButton = document.getElementById("add-color-button");
  addButton.disabled = !enabled;
}

/*
function updateRemoveStatus() {
  var removeButton = document.getElementById("color-remove-0");
  removeButton.disabled = colorCount == 1;
}*/


function setColor(index, value, updating) {
  if (index < 0 || index >= criteriaCount) throw "Invalid index: " + index;
  if (updating) {
    if (index == getActiveIndex()) {
      selector.setValue(activeInput.value);
    }
  } else {
    var input = document.getElementById("color-input-" + index)
    if (input.value != value) input.value = value;
  }
  var sample = document.getElementById("color-sample-" + index);
  if (sample) {
    var color = hexToRgb(value);
    if (color) {
      sample.style.background = "#"+value;
      sample.style.border = "1px solid black";
    } else {
      sample.style.background = "";
      sample.style.border = "none";
    }
  }
  //TODO
  //updateAddStatus();
}

function setTag(index, value) {
  //TODO needs rel too
}

function criteriaRow(el) {
  while (el && el.tagName != "TR") el = el.parentNode;
  return el;
}

function criteriaIndex(el) {
  el = criteriaRow(el);
  if (!el) return null;
  var id = el.id;
  if (!id) return null;
  var parts = id.split("-");
  if (parts.length < 3) return null;
  var i = parseInt(parts[2]);
  if (isNaN(i)) return null;
  return i;
}

function criteriaType(el) {
  el = criteriaRow(el);
  if (!el) return null;
  var cn = el.className;
  if (!cn) return null;
  var parts = cn.split("-");
  if (parts.length < 2) return null;
  if (parts[1] != "row") return null;
  return parts[0];
}

function addCriteria(type) {
  var countName = type + "Count";
  
  if (window[countName] >= window[type+"CountMax"]) return false;
  if (criteriaCount >= criteriaCountMax) return false;

  var body = document.getElementById("color-body");
  var tr = document.createElement("tr");
  tr.id = "criteria-row-" + criteriaCount;
  tr.className = type + "-row";
  var html = "";
  html += '<label id="criteria-numeral-$" class="numeral">*</label>'
  switch(type) {
    case "tag" :
      html += '|<input id="^-input-$" class="^-input" name="^-%" type="TEXT">'
      html += '|<select id="^-relation-$" class="tag-relation" name="^rel-%"><option value="req">required</option><option value="des">desired</option><option value="unw">unwanted</option><option value="for">forbidden</option></select>';
      break;
    case "color" :
      html += '|<input id="^-input-$" class="^-input" name="^-%" type="TEXT" onfocus="setActiveInput(this)" onchange="setColor(criteriaIndex(this),this.value, true)" onkeyup="setColor(criteriaIndex(this),this.value, true)">'
      html += '|<div id="^-sample-$" class="small-sample" onclick="document.getElementById(\'^-input-\'+criteriaIndex(this)).focus()"></div>';
      break;
  }
  html += '|<button id="criteria-remove-%" onclick="removeCriteria(criteriaIndex(this)); return false"><img src="/images/color-search/remove16x16.png" alt="Remove ^"></button>';
  html = html.replace(/\^/g, type);
  html = html.replace(/\%/g, window[countName]);
  html = html.replace(/\$/g, criteriaCount);
  html = html.replace(/\*/g, criteriaCount+1);
  var htmls = html.split("|");
  var widths = [40, 100, 100, 50];
  for(var i = 0; i < htmls.length; i++) {
    var td = document.createElement("td");
    td.style.width = widths[i] + "px";
    td.style.textAlign="center";
    td.innerHTML = htmls[i];
    tr.appendChild(td);
  }
  var addTr = document.getElementById("bottom-divide-row");
  body.insertBefore(tr, addTr);
  criteriaCount++;
  window[countName]++;
  updateButtons();
  return true;
}

function removeCriteria(index) {
  var tr = document.getElementById("criteria-row-" + index);
  var type = tr.className.split("-")[0];
  var countName = type + "Count";
  if (window[countName] == 0) return false;
  
  if (index == getActiveIndex()) setActiveInput(null);

  var counts = { tag: 0, color: 0 }
  var newId = 0;    
  for (var oldId = 0; oldId < criteriaCount; oldId++) {
    if (oldId == index) continue;
    var row = document.getElementById("criteria-row-"+oldId);
    var type = criteriaType(row);
    update("criteria-row-");
    update("criteria-numeral-");
    update(type+"-input-");
    update(type+"-relation-");
    update(type+"-sample-");
    update("criteria-remove-");
    counts[type]++;
    newId++;
  }
  var body = document.getElementById("color-body");
  body.removeChild(tr);

  window[countName]--;
  criteriaCount--;
  updateButtons();
  
  function update(prefix) {
    var el = document.getElementById(prefix+oldId);
    if (!el) return;
    el.id = prefix+newId;
    //special cases
    if (prefix == "criteria-numeral-") {
      el.innerHTML = newId+1;
    }
    if (prefix == "tag-relation-") {
      el.name = "tagrel-" + counts[type];
    }
    var nm = el.name;
    if (nm) {
      var parts = nm.split("-");
      if (parts.length == 2) {
        el.name = parts[0] + "-" + counts[type]; 
      }
    }
  }
}

function addColor() {
  if (addCriteria("color")) {
    setColor(criteriaCount-1, selector.getValue(), false);
    setActiveInput(null);
  }
}

function addTags() {
  var input = document.getElementById("tags");
  if (!input) return;
  var str = input.value;
  input.value = "";
  var tags = str.split(/\s+/);
  for (var i = 0 ; i < tags.length; i++) {
    tag = tags[i];
    if (!tag) continue;
    var veto = false;
    for (var j = 0; j < criteriaCount; j++) {
      var input = document.getElementById("tag-input-"+j);
      if (!input) continue;
      if (input.value != tag) continue;
      veto = true;
      break;
    }
    if (!veto) {
      if ( addCriteria("tag") ) {
        var input = document.getElementById("tag-input-"+(criteriaCount-1));
        input.value = tag;
        input.focus();
      }
    }
  }
}

function init() {
  selector = makeColorSelector(function(rgb) {
    var i = getActiveIndex();
    if (i == -1) return;
    var oldColor = hexToRgb(activeInput.value);
    if (oldColor == null && rgb == null) return;
    if (oldColor != null && oldColor.r == rgb.r && oldColor.g == rgb.g && oldColor.b == rgb.b) return;
    var value = rgbToHex(rgb);
    setColor(i, value);
  });
  selector.setRGB({r: 0, g: 0, b: 0});
  document.getElementById("selector").appendChild(selector.element);
  updateButtons();
}
