/**
  * Restore a string to an array. 
  *
  * PHP API Extension
  * 
  * Example
  * <code>
  * $string = 'A,B,indC:C,(0:D,1:E),indF:F'
  * $array = string_to_array($string)
  * <code>
  * Output:
  * <code>
  * array('A', 'B', 'indC' => 'C', array('D', 'E'), 'indF'=>'F');
  * </code>
  *
  * @access public
  * @static
  * @param string $string
  * @param string $hashsep A character to be used as a hash key and val seperator
  * @param string $elemsep A character to be used as a elememt separator
  * @param string $openarray A character to be used as an open bracket of an array
  * @param string $closearray A character to be used as a close bracket of an array
  * @param boolean $decode Performe decode key/val
  * @return array
  * @see array_to_string
  * @version $Id: v 1.3 2008-07-15 11:14:46 sonots $
  */
 function string_to_array($string, $hashsep = ':', $elemsep = ',', $openarray = '(', $closearray = ')', $decode = true)
 {
     $result = array();
     $delims = $hashsep . $elemsep . $openarray . $closearray;
     if ($string === '') {
         return $result;
     }
     /// parse the first element
     $hashsep_pos = strpos($string, $hashsep);
     $elemsep_pos = strpos($string, $elemsep);
     $openarray_pos = strpos($string, $openarray);
     // there is a key or not for the 1st element
     if ($hashsep_pos !== false && ($elemsep_pos === false || $hashsep_pos < $elemsep_pos) && ($openarray_pos === false || $hashsep_pos < $openarray_pos)) {
         $key = substr($string, 0, $hashsep_pos);
         $key = $decode ? sonots::urldecode($key, $delims) : $key;
         $string = trim(substr($string, $hashsep_pos + 1));
     } else {
         $key = null;
     }
     $openarray_pos = strpos($string, $openarray);
     if ($openarray_pos === false || $openarray_pos > 0) {
         // hash val is not an array
         $elemsep_pos = strpos($string, $elemsep);
         if ($elemsep_pos === false) {
             $val = $decode ? sonots::urldecode($string, $delims) : $string;
             $string = "";
         } else {
             $val = substr($string, 0, $elemsep_pos);
             $val = $decode ? sonots::urldecode($val, $delims) : $val;
             $string = substr($string, $elemsep_pos + 1);
         }
     } elseif ($openarray_pos == 0) {
         // hash val is an array
         $string = substr($string, 1);
         $num_openarray = 1;
         // search where is a corresponding closet
         $string_char_array = str_split($string);
         for ($index = 0; count($string_char_array); $index++) {
             if ($string_char_array[$index] == $openarray) {
                 $num_openarray++;
             } else {
                 if ($string_char_array[$index] == $closearray) {
                     $num_openarray--;
                 }
             }
             if ($num_openarray == 0) {
                 break;
             }
         }
         $val = sonots::string_to_array(substr($string, 0, $index), $hashsep, $elemsep, $openarray, $closearray, $decode);
         $string = substr($string, $index + 2);
     }
     if (is_null($key)) {
         $result[] = $val;
     } else {
         $result[$key] = $val;
     }
     /// next element
     if (strlen($string) != 0) {
         $result = array_merge($result, sonots::string_to_array($string, $hashsep, $elemsep, $openarray, $closearray, $decode));
     }
     return $result;
 }