/* --------------------------------------------------------------------------------------
 * showhide.js
 * version 1.01
 * @2009.05.21
 * Required common.js ver1.40 later
-------------------------------------------------------------------------------------- */
function fncShowHide(targetId, opts) {
  new VCOMN.ShowHide(targetId, opts);
}

VCOMN.ShowHide = function () {
  this.initialize.apply(this, arguments);
}

VCOMN.ShowHide.prototype = {
  OPEN_CLASS: 'open',
  CLOSE_CLASS: 'close',
  SHOW_ALL_CLASS: 'showAll',
  HIDE_ALL_CLASS: 'hideAll',
  DIV_ALL_ID: 'showhideAll',
  DIV_ALL_POS: 'top',
  SHOW_ALL_HTML: 'Expand All',
  HIDE_ALL_HTML: 'Collapse All',
  IS_COOKIE: false,
  COOKIE_NAME: 'vcom_showhide',
  COOKIE_DAY: null,
  initialize: function (targetId, opts) {
    opts = opts || {};
    this.opts = {};
    this.opts.openClass = typeof opts.openClass == 'string' ? opts.openClass : this.OPEN_CLASS;
    this.opts.closeClass = typeof opts.closeClass == 'string' ? opts.closeClass : this.CLOSE_CLASS;
    this.opts.showAllClass = typeof opts.showAllClass == 'string' ? opts.showAllClass : this.SHOW_ALL_CLASS;
    this.opts.hideAllClass = typeof opts.hideAllClass == 'string' ? opts.hideAllClass : this.HIDE_ALL_CLASS;
    this.opts.divAllId = typeof opts.divAllId == 'string' ? opts.divAllId : this.DIV_ALL_ID;
    this.opts.divAllPos = opts.divAllPos || this.DIV_ALL_POS;
    this.opts.showAllHtml = opts.showAllHtml || this.SHOW_ALL_HTML;
    this.opts.hideAllHtml = opts.hideAllHtml || this.HIDE_ALL_HTML;
    this.opts.isCookie = typeof opts.isCookie != 'undefined' ? opts.isCookie : this.IS_COOKIE;
    this.opts.cookieName = opts.cookieName || this.COOKIE_NAME;
    this.opts.cookieDay = typeof opts.cookieDay != 'undefined' ? opts.cookieDay : this.COOKIE_DAY;
    this.opts.linkClass = opts.linkClass || false;
    this.opts.linkInvalid = opts.linkInvalid || false;
    this._initList(targetId);
  },
  _initList: function (targetId) {
    var targetElem = document.getElementById(targetId);
    if (!targetElem || !targetElem.childNodes) return false;
    if (this.opts.isCookie) {
      var cookie = VCOMN.getCookie(this.opts.cookieName);
      if (cookie) {
        var cookies = cookie.split('-');
      }
    }
    this.lists = [];
    var elems = targetElem.getElementsByTagName('*');
    for (var i = 0; i < elems.length; i++) {
      var elem = elems[i];
      var len = elems.length;
      var isOpen = undefined;
      if (VCOMN.hasClass(elem, this.opts.openClass)) {
        isOpen = true;
      } else if (VCOMN.hasClass(elem, this.opts.closeClass)) {
        isOpen = false;
      }
      if (isOpen !== undefined) {
        if (cookies && cookies[this.lists.length]) {
          isOpen = +cookies[this.lists.length];
        }
        this._initContent(elem, isOpen);
      }
      if (len != elems.length) {
        i += elems.length - len;
      }
    }
    var div = document.createElement('DIV');
    if (this.opts.divAllId) div.id = this.opts.divAllId;
    var span = document.createElement('SPAN');
    span.className = (cookies && !+cookies[this.lists.length]) ? this.opts.hideAllClass : this.opts.showAllClass;
    span.innerHTML = (cookies && !+cookies[this.lists.length]) ? this.opts.hideAllHtml : this.opts.showAllHtml;
    this._initAllControl(span);
    div.appendChild(span);
    if (this.opts.divAllPos == 'top') {
      targetElem.parentNode.insertBefore(div, targetElem);
    } else {
      targetElem.parentNode.insertBefore(div, targetElem.nextSibling);
    }
  },
  _initAllControl: function (targetElem) {
    VCOMN.EventObserve(targetElem, 'click', VCOMN.bindFunc(this.clickAllControl, this), false);
    this.allControl = targetElem;
  },
  _initContent: function (targetElem, isOpen) {
    var span = document.createElement('SPAN');
    span.className = isOpen ? this.opts.openClass : this.opts.closeClass;
    VCOMN.removeClass(targetElem, this.opts.openClass);
    VCOMN.removeClass(targetElem, this.opts.closeClass);
    var firstChild = undefined;
    var secondChild = undefined;
    var i = 0;
    while (firstChild = targetElem.childNodes[i]) {
      i++;
      if (firstChild.nodeType == 1) break;
      if (!firstChild.nodeValue.match(/^[\s]*$/)) break;
    }
    if (firstChild) {
      while ((secondChild = targetElem.childNodes[i]) && targetElem.childNodes[i++].nodeType != 1);
      if (firstChild.nodeType == 1 && firstChild.tagName.toUpperCase() == 'A') {
        if (this.opts.linkClass) {
          VCOMN.addClass(firstChild, this.opts.linkClass);
        }
        if (this.opts.linkInvalid) {
          firstChild.onclick = function () {return false;};
          firstChild._linkInvalid = true;
          span.appendChild(firstChild);
        }
      } else {
        span.appendChild(firstChild);
      }
      span.appendChild(firstChild);
    }
    if (secondChild && secondChild.nodeType == 1) {
      secondChild.style.display = isOpen ? 'block' : 'none';
    }
    targetElem.insertBefore(span, targetElem.firstChild);
    VCOMN.EventObserve(span, 'click', VCOMN.bindFunc(this.clickParent, this, this.lists.length), false);
    this.lists[this.lists.length] = {parent:span, content: secondChild};
  },
  clickAllControl: function () {
    var isOpen = VCOMN.hasClass(this.allControl, this.opts.showAllClass);
    VCOMN.addClass(this.allControl, isOpen ? this.opts.hideAllClass : this.opts.showAllClass);
    VCOMN.removeClass(this.allControl, isOpen ? this.opts.showAllClass : this.opts.hideAllClass);
    this.allControl.innerHTML = isOpen ? this.opts.hideAllHtml : this.opts.showAllHtml;
    for (var i = 0; i < this.lists.length; i++) {
      this.listOpenClose(this.lists[i], isOpen);
    }
    this.saveCookie();
  },
  clickParent: function (index, e) {
    var targetElem = e.target ? e.target : event ? event.srcElement : null;
    if (targetElem && targetElem.tagName.toUpperCase() == 'A' && !targetElem._linkInvalid) {
      return;
    }
    var list = this.lists[index];
    if (!list) return;
    this.listOpenClose(list, !VCOMN.hasClass(list.parent, this.opts.openClass));
    this.saveCookie();
  },
  listOpenClose: function (list, isOpen) {
    VCOMN.addClass(list.parent, isOpen ? this.opts.openClass : this.opts.closeClass);
    VCOMN.removeClass(list.parent, isOpen ? this.opts.closeClass : this.opts.openClass);
    list.content.style.display = isOpen ? 'block' : 'none';
  },
  saveCookie: function () {
    if (!this.opts.isCookie) return;
    var values = [];
    for (var i = 0; i < this.lists.length; i++) {
      values[values.length] = VCOMN.hasClass(this.lists[i].parent, this.opts.openClass) ? 1 : 0;
    }
    values[values.length] = VCOMN.hasClass(this.allControl, this.opts.showAllClass) ? 1 : 0;
    VCOMN.setCookie(this.opts.cookieName, values.join('-'), this.opts.cookieDay, null, '/');
  }
}


