// configure parameter
//var CONFINE   = '_';   // confined prefixed charactor (string) which to not regist cookie.
var SEPARATOR = ':';   // separator between name & value.
var BOUNDARY  = '/';   // boundary of name & value set
var EXPIRE    = 9;     // expire date (unit is day)

var ERROR_MESSAGE_FOR_NO_COOKIE = 'not have a valid cookie data.';

// un-public function -----------------------------------------
// get from form element value
function getTextValue(obj)          {  return obj.name + SEPARATOR + obj.value + BOUNDARY; }
function getSelectOneValue(obj)     {  return obj.name + SEPARATOR + obj.selectedIndex + BOUNDARY; }
function getCheckboxValue(obj)      {  return obj.name + SEPARATOR + obj.checked + BOUNDARY; }
function getRadioValue(obj)         {  return obj.checked ? (obj.name + SEPARATOR + obj.value + BOUNDARY) : ''; }
function getSelectMultipleValue(obj){
  var selectedOption = '';
  
  for(optionIndex = 0; optionIndex < obj.options.length; optionIndex++ ){
    if( obj.options[optionIndex].selected == true ){
      selectedOption += obj.name + SEPARATOR + optionIndex + BOUNDARY;
    }
  }
  
  return selectedOption;
}

// set to form element
function setTextValue(value, obj)          {  obj.value = value; }
function setSelectOneValue(value, obj)     {  obj.selectedIndex = value; }
function setSelectMultipleValue(value, obj){  obj.options[value].selected = true; }
function setCheckboxValue(value, obj)      {  obj.checked = value; }
function setRadioValue(value, obj)         {  obj.checked = (obj.value == value ?  true : false); }

// cookie proc.
function getTargetCookieData(name){
//  var temp = document.cookie.split(/\s*;\s*/);
  var temp = document.cookie.split('; ');
  
  // search my cookie data
  for( index = 0; index < temp.length; index++ ){
    var piece = temp[index].split('=');
    
    if( (piece[0] == name) && (piece[1] != undefined) ){
      return unescape(piece[1]);
    }
  }

  return undefined;  // not found
}

// obj: target of cookie data. (form object)
// return: non-escaped string data by devide BOUNDERY & SEPARATOR
//         ex. srt:1/dex:2/luk:3/
function getCookieData(obj){
  var result = '';

  for( index = 0; index < obj.elements.length; index++ ){
    // skip not assigned name element
    if( !obj.elements[index].name ){ continue; }
    // skip no-regist element
//    if( obj.elements[index].name.substr(-CONFINE.length, CONFINE.length) == CONFINE ){ continue; }
//    if( obj.elements[index].name.substr(obj.elements[index].name.length-CONFINE.length, CONFINE.length) == CONFINE ){ continue; }
    if( obj.elements[index].readOnly == true ){ continue; }
    
    // proc. each type
    switch( obj.elements[index].type.toLowerCase() ){
    case 'text':
      result += getTextValue(obj.elements[index]);
      break;
    
    case 'select-one':
      result += getSelectOneValue(obj.elements[index]);
      break;
    
    case 'select-multiple':
      result += getSelectMultipleValue(obj.elements[index]);
      break;
    
    case 'checkbox':
      result += getCheckboxValue(obj.elements[index]);
      break;
    
    case 'radio':
      result += getRadioValue(obj.elements[index]);
      break;
    
    default:
    }
  }
  
  return result;
}

// str: non-escaped string data. (same format of getCookieData() return value)
// obj: target of setting form object
// return: nothing
function setFormDataByCookie(str,obj){
  var parts = str.split(BOUNDARY);

  while( parts.length ){
    var temp = parts.pop().split(SEPARATOR);
    
    // skip not assigned name element
    if( !temp[0] ){ continue; }
    
    // search target element
    for( index = 0; index < obj.elements.length; index ++ ){
      if( obj.elements[index].name == temp[0] ){
        // found out!
        
        // proc. each type
        switch( obj.elements[index].type.toLowerCase() ){
        case 'text':
          setTextValue(temp[1], obj.elements[index]);
          break;
        
        case 'select-one':
          setSelectOneValue(temp[1], obj.elements[index]);
          break;
        
        case 'select-multiple':
          setSelectMultipleValue(temp[1], obj.elements[index]);
          break;
        
        case 'checkbox':
          setCheckboxValue(temp[1], obj.elements[index]);
          break;
        
        case 'radio':
          setRadioValue(temp[1], obj.elements[index]);
          continue;  // may exist another radio element.
        
        default:
        }
        
        // to next part
        break;
      }
    }
  }
}

// methods ----------------------------------------------------
function setTargetObj(obj){
  if( obj != undefined ){
    this.target = obj;
  }

  return false;  // to not jump by anchor
}

function setCookieName(name){
  this.cookieName = name;
  
  return false;  // to not jump by anchor
}

function writeCookie(){
  var str    = escape(getCookieData(this.target));
  var expire = new Date();
  
  // compute expire time, expire after 3 days.
  expire.setTime( expire.getTime() + EXPIRE * 24 * 60 * 60 * 1000);
  
  if( this.cookieName == undefined ){
    document.cookie = this.target.name + '=' + str + ';expires=' + expire.toGMTString() + ';';
  } else{
    document.cookie = this.cookieName + '=' + str + ';expires=' + expire.toGMTString() + ';';
  }
  
//alert(this.target.name + '=' + str + ';expires=' + expire.toGMTString() + ';');
  return;

  return false;  // to not jump by anchor
}

function readCookie(){
  if( this.cookieName == undefined ){
    var str = getTargetCookieData(this.target.name);
  } else{
    var str = getTargetCookieData(this.cookieName);
  }
  
  if( str != undefined ){
    setFormDataByCookie(str, this.target);
  } else{
    alert(ERROR_MESSAGE_FOR_NO_COOKIE);
  }

  return false;  // to not jump by anchor
}

function printCookieStr(){
//alert(document.cookie);
  var str = getTargetCookieData(this.target.name);
  
  if( str != undefined ){
    alert(str);
  } else{
    alert(ERROR_MESSAGE_FOR_NO_COOKIE);
  }
  
  return false;  // to not jump by anchor
}

function deleteCookie(){
  var expire = new Date(0);
  document.cookie = this.target.name + '=;expires=' + expire.toGMTString() + ';';
  
  return false;  // to not jump by anchor
}

// class ------------------------------------------------------
function localCookie(obj, name){
  // constructor
  if( obj != undefined ){
    this.target = obj;
  }
  if( name != undefined ){
    this.cookieName = name;
  } else{
    this.cookieName = undefined;
  }
  
  // public methods
  this.set   = setCookieName;
  this.save  = writeCookie;
  this.load  = readCookie;
  this.view  = printCookieStr;
  this.clear = deleteCookie;
}
