var CF = {};
CF.MasterData = {};
CF.Helpers = {};

CF.MasterData.onLoad = function(data) {
  $H(data).each( function(pair) { CF.MasterData[pair.key] = pair.value; });
};

CF.MasterData.getRelations = function(parentMasterName, childMasterName) {
  var relationName = parentMasterName + '_' + childMasterName;
  var relations = CF.MasterData[relationName];
  if (relations == undefined) {
    return {};
  }
  return relations;
};

CF.Helpers.onParentSelectChange = function(parentSelect, childSelect, parentMasterName, childMasterName) {
  parentSelect = $(parentSelect);
  childSelect = $(childSelect);

  // 現在存在するoption要素を削除。未選択時のテキストを保存。
  var prompt = '選択してください';
  while (childSelect.childNodes.length > 0) {
    var lastChild = childSelect.lastChild;
    if (lastChild.value == '') {
      prompt = lastChild.innerHTML;
    }
    childSelect.removeChild(lastChild);
  }

  // childのoptionに使う値を取得
  var values =  Array($F(parentSelect)).flatten();
  var relations = CF.MasterData.getRelations(parentMasterName, childMasterName);
  var children = values.inject([], function(result, value) {
    return result.concat(relations[value]);
  }).without(undefined).sort(function(a, b){return (a-b);});

  // optionを追加。
  var promptOption = Builder.node('option', { value: '' }, prompt);
  childSelect.appendChild(promptOption);

  var master = CF.MasterData[childMasterName];
  children.each(function(c) {
    var option = Builder.node('option', { value: c }, master[c]);
    childSelect.appendChild(option);
  });

  // 先頭のprompt用オプションを選択
  childSelect.value = '';
  
  // 子供の onchange イベントを発生させる
  if (typeof(childSelect.onchange) == 'function') {
    childSelect.onchange();
  }
};

CF.Helpers.onSelectWithChecksChange = function(select, parentMasterName, childMasterName) {
  select = $(select);
  var checkBoxDiv = select.up().next();
  var key = checkBoxDiv.id.split('-')[0];
  var name = checkBoxDiv.id.split('-')[1];
  
  // 子供の div の中身を空にする
  checkBoxDiv.innerHTML = '';
  
  // 子供のチェックボックスに使う値を取得
  var values =  Array(select.value).flatten();
  var relations = CF.MasterData.getRelations(parentMasterName, childMasterName);
  var children = values.inject([], function(result, value) {
    return result.concat(relations[value]);
  }).without(undefined).sort(function(a, b){return (a-b);});
  
  // 子供の div の中身を作る
  // dvi > ul > li > label > input, text
  var master = CF.MasterData[childMasterName];
  var listItems = children.collect(function(code) {
    var childId = [key, name, code].join('_');
    var text = master[code];
    var input = Builder.node('input', { type: 'checkbox', id: childId, name: name + '[]', value: code});
    var label = Builder.node('label', {htmlFor: childId}, [input, text]);
    var li = Builder.node('li', label);
    return li;
  });
  var ul = Builder.node('ul', listItems);
  checkBoxDiv.appendChild(ul);
};

CF.Helpers.onStackableAddClick = function(e) {
  e = $(e);
  var lastDiv = e.up().previous();
  lastDiv.id.match(/^(.*)-(\d+)$/);
  var key = RegExp.$1;
  var lastIndex = parseInt(RegExp.$2);
  var newIndex = lastIndex + 1;
  var newDiv = Builder.node('div', { id: key + '-' + newIndex});

  var selects = lastDiv.select('select');

  // parent
  selects[0].name.match(/^(.*)_(\d+)$/);
  var newParentSelect = Builder.node('select', { name: RegExp.$1 + '_' + newIndex } );
    $A(selects[0].options).each(function(option) {
      newParentSelect.insert(Builder.node('option', { value: option.value }, option.innerHTML ));
    });
  newParentSelect.value = '';
  newDiv.insert(newParentSelect);
  newParentSelect.onchange = selects[0].onchange;

  // child
  selects[1].name.match(/^(.*)_(\d+)$/);
  var newChildSelect = Builder.node('select', { name: RegExp.$1 + '_' + newIndex } );
  var prompt = selects[1].options[0];
  newChildSelect.insert(Builder.node('option', { value: prompt.value }, prompt.innerHTML ));
  newDiv.insert(newChildSelect);

  // delete
  var lastDelLink = lastDiv.select('a')[0];
  var delLink = Builder.node('a', { href: '#' });
  delLink.onclick = lastDelLink.onclick;
  delLink.innerHTML = lastDelLink.innerHTML;
  newDiv.insert(delLink);

  e.up().insert({ before: newDiv });
};

CF.Helpers.onStackableDeleteClick = function(e) {
  var div = $(e).up();
  div.id.match(/^(.*)-\d+$/);
  var re = new RegExp('^' + RegExp.$1 + '-\\d+$');
  var prevNode = div.previous();
  var nextNode = div.next();
  if ((prevNode && prevNode.id.match(re)) || (nextNode && nextNode.id.match(re))) {
    div.remove();
  }
};

CF.Helpers.onTextFieldLoad = function(textField, prompt) {
  textField = $(textField);
  if (textField.value == '') {
    textField.value = prompt;
    textField.removeClassName('hasGainedFocus');
    textField.addClassName('hasNotGainedFocus');
  } else {
    textField.removeClassName('hasNotGainedFocus');
    textField.addClassName('hasGainedFocus');
  }
};
CF.Helpers.onTextFieldFocus = function(textField) {
  textField = $(textField);
  if (textField.hasClassName('hasNotGainedFocus')) {
    textField.value = '';
    textField.removeClassName('hasNotGainedFocus');
    textField.addClassName('hasGainedFocus');
  }
};
CF.Helpers.onSearchSubmit = function(form) {
  $(form).select('input[type=text][class=hasNotGainedFocus]').each(function(tf) { tf.value = ''; });
  return true;
};
