// Class: Struct
// Author: Shuns (www.netgrow.com.au)
// Last Updated: 22/09/06
// Version: 1.06

Struct=function(o){this._keys=[];this._addedFunctions=[];this._reservedWords='';this._errorHandling=true;this._errorCallback=this._handleError;this._setReservedWords();this.insertObject(o);};Struct.prototype.errorHandling=function(b, fn){this._errorHandling=this._returnBoolean(b);if(typeof fn=='function'){this._errorCallback=fn;}return this;};Struct.prototype.wordReserved=function(s){return this._searchArray(s, this._reservedWords.split('|'))!=null ? true : false;};Struct.prototype.dump=function(showTypes, object){var Struct=this;var dump='';var st=typeof showTypes=='undefined' ? true : this._returnBoolean(showTypes);var obj=typeof object=='undefined' ? this : object;function recurse(o, type){var i;var j=0;var r='';var args=null;for(i in o){if(!Struct.wordReserved(i)){var t=Struct._isArray(o[i])? 'array' : typeof o[i];if(j < 1){r+='<table'+Struct._dumpStyles(type,'table')+'><tr><th colspan="2"'+Struct._dumpStyles(type,'th')+'>'+type+'</th></tr>';j++;}if(typeof o[i]=='object'){r+='<tr><td'+Struct._dumpStyles(type,'td-key')+'>'+i+(st ? ' ['+t+']' : '')+'</td><td'+Struct._dumpStyles(type,'td-value')+'>'+recurse(o[i], t)+'</td></tr>';}else if(typeof o[i]=='function'){var a=o[i].toString().match(/^.*function.*?\((.*?)\)/im)[1];args=(a==null||typeof a=='undefined'||a=='')? 'none' : a;r+='<tr><td'+Struct._dumpStyles('object','td-key')+'>'+i+(st ? ' ['+t+']' : '')+'</td><td'+Struct._dumpStyles(type,'td-value')+'><table'+Struct._dumpStyles(t,'table')+'><tr><th colspan="2"'+Struct._dumpStyles(t,'th')+'>'+typeof o[i]+'</th></tr>';r+='<tr><td colspan="2"'+Struct._dumpStyles('function','td-value')+'><table'+Struct._dumpStyles('arguments','table')+'><tr><td'+Struct._dumpStyles('arguments','td-key')+'><i>Arguments: </i></td><td'+Struct._dumpStyles(type,'td-value')+'>'+args+'</td></tr><tr><td'+Struct._dumpStyles('arguments','td-key')+'><i>Function: </i></td><td'+Struct._dumpStyles(type,'td-value')+'>'+o[i]+'</td></tr></table></td></tr></table></td></tr>';}else{r+='<tr><td'+Struct._dumpStyles(type,'td-key')+'>'+i+(st ? ' ['+t+']' : '')+'</td><td'+Struct._dumpStyles(type,'td-value')+'>'+o[i]+'</td></tr>';}}}if(j==0){r+='<table'+Struct._dumpStyles(type,'table')+'><tr><th colspan="2"'+Struct._dumpStyles(type,'th')+'>'+type+' [empty]</th></tr>';}r+='</table>';return r;};try{dump+=recurse(obj,(this._isArray(obj)? 'array' : typeof obj));this._openStructWindow('dumpWin', 760, 500, dump, 'Struct Dump', 'function tRow(s){t=s.parentNode.lastChild;tTarget(t, tSource(s));}function tTable(s){var switchToState=tSource(s);var table=s.parentNode.parentNode;for(var i=1;i < table.childNodes.length;i++){t=table.childNodes[i];if(t.style){tTarget(t, switchToState);}}}function tSource(s){if(s.style.fontStyle=="italic"||s.style.fontStyle==null){s.style.fontStyle="normal";s.title="click to collapse";return "open";}else{s.style.fontStyle="italic";s.title="click to expand";return "closed";}}function tTarget(t, switchToState){if(switchToState=="open"){t.style.display="";}else{t.style.display="none";}}');}catch(e){this._errorCallback(e);}};Struct.prototype.getFunctions=function(pos){var Struct=this;var a=[];var p=typeof pos=='undefined'||isNaN(pos)? null : pos;function getFunction(obj){var i;for(i in obj){var fn={};if(typeof obj[i]=='function' && !Struct.wordReserved(i)){fn.key=i;fn.value=obj[i];a.push(fn);}if(typeof obj[i]=='object'){getFunction(obj[i]);}}};getFunction(this);return p==null||(p < 0||p >=a.length)? a : a[p];};Struct.prototype.isEmpty=function(){return this._keys.length==0 ? true : false;};Struct.prototype.count=function(o){var i;var j=0;var obj=!o ? this : o;for(i in obj){if(!this.wordReserved(i)){if(typeof obj[i]=='object'){j+=this.count(obj[i])+1;}else if(typeof this[i]!='function'||(typeof this[i]=='function' && this._searchArray(i, this._addedFunctions)!=null)){j++;}}}return j;};Struct.prototype.deleteItem=function(k, updateKeys){var Struct=this;var uk=typeof updateKeys=='undefined' ? true : this._returnBoolean(updateKeys);var p=null;if(!this.wordReserved(k)){p=this._parsePath(k);function getSearch(o, c){var i;var j=c;for(i in o){if(!Struct.wordReserved(i)){if(i==p[p.length-1]&& i==p[c]&& j==p.length-1){if(Struct._isArray(o)){var l=o.length;o.splice(i, 1);if(o.length !=l-1){delete o[i];}}else{delete o[i];}break;}else if(typeof o[i]=='object' && p.length !=1 && i==p[c]){getSearch(o[i], j+=1);}}}};getSearch(this, 0);if(uk){this._updateKeys();}return this;}return false;};Struct.prototype.clear=function(){for(i in this){this.deleteItem(i, false);}this._updateKeys();return this;};Struct.prototype.append=function(s, overWrite){var ow=typeof overWrite !='undefined' && overWrite==true ? true : false;try{if(typeof s=='object'){this.insertObject(s, ow);}}catch(e){this._errorCallback(e);return false;}return this;};Struct.prototype.insert=function(k, v, overWrite){var ow=typeof overWrite !='undefined' && overWrite==true ? true : false;var Struct=this;var p=null;if(!this.wordReserved(k)){p=this._parsePath(k);function getSearch(o, c){var i;var j=c;var x=0;for(i in o){if(!Struct.wordReserved(i)){x++;if((p[p.length-1]==p[c]&& typeof o[p[c]]=='undefined' && j==p.length-1)||(i==p[p.length-1]&& i==p[c]&& j==p.length-1 && ow)){try{o[p[c]]=v;Struct._updateKeys();break;}catch(e){this._errorCallback(e);return false;}}else if(typeof o[i]=='object' && p.length !=1 && i==p[c]){getSearch(o[i], j+=1);}}}if(x < 1){try{o[p[c]]=v;Struct._updateKeys();}catch(e){this._errorCallback(e);return false;}}};if(p.length==1){try{if(typeof this[k]=='undefined'||ow){this[k]=v;this._updateKeys();}}catch(e){this._errorCallback(e);return false;}}else{getSearch(this, 0);}return this;}};Struct.prototype.insertObject=function(o, overWrite, path){var i;var ow=typeof overWrite !='undefined' && overWrite==true ? true : false;try{for(i in o){this.insert((typeof path !='undefined' ? path+'["'+i+'"]' : i), o[i], ow);}}catch(e){this._errorCallback(e);return false;}return this;};Struct.prototype.update=function(k, nv){var Struct=this;var p=null;if(!this.wordReserved(k)){p=this._parsePath(k);function getSearch(o, c){var i;var j=c;for(i in o){if(!Struct.wordReserved(i)){if(p[p.length-1]==p[c]&& typeof o[p[c]]=='undefined' && j==p.length-1){o[p[c]]=nv;Struct._updateKeys();break;}else if(i==p[p.length-1]&& i==p[c]&& j==p.length-1){if(Struct._isArray(o)){if(o[p[c]]){o[p[c]]=nv;}else{var l=o.length;o.push(nv);if(o.length !=l+1){o[i]=nv;}}}else{o[i]=nv;}Struct._updateKeys();break;}else if(typeof o[i]=='object' && p.length !=1 && i==p[c]){getSearch(o[i], j+=1);}}}};getSearch(this, 0);return this;}return false;};Struct.prototype.renameKey=function(k, nn){var Struct=this;var p=null;if(!this.wordReserved(k)){p=this._parsePath(k);function getSearch(o, c){var i;var j=c;for(i in o){if(!Struct.wordReserved(i)){if(i==p[p.length-1]&& i==p[c]&& j==p.length-1){o[nn]=o[p[c]];delete o[i];Struct._updateKeys();break;}else if(typeof o[i]=='object' && p.length !=1 && i==p[c]){getSearch(o[i], j+=1);}}}};getSearch(this, 0);return this;}return false;};Struct.prototype.searchPath=function(o, c, fn, p){var i;var j=c;for(i in o){if(!this.wordReserved(i)){if(i==p[p.length-1]&& i==p[c]&& j==p.length-1){fn(o[i]);break;}else if(typeof o[i]=='object' && p.length !=1 && i==p[c]){this.searchPath(o[i], j+=1, fn, p);}}}};Struct.prototype.getFromPath=function(k){var Struct=this;var p=null;var r=null;if(!this.wordReserved(k)){p=this._parsePath(k);this.searchPath(this, 0, function(v){r=v;}, p);}return r;};Struct.prototype.findKeys=function(k){if(!this.wordReserved(k)){var keys=[];function searchStruct(k, o){var i;var obj=!o ? this : o;for(i in obj){if(i==k){keys.push(obj[i]);}if(typeof obj[i]=='object'){searchStruct(k, obj[i]);}}};searchStruct(k, this);return keys;}return null;};Struct.prototype.findValue=function(v, RESearch, getFunctions){var Struct=this;var values=[];var useRegEx=!RESearch ? false : true;var getFn=!getFunctions ? false : true;var regExp=null;if(useRegEx){try{regExp=new RegExp(v);}catch(e){this._errorCallback(e);return false;}}function searchStruct(v, o, useRegEx, regExp, getFn){var i;var obj=!o ? this : o;for(i in obj){var r={};if((!useRegEx && obj[i]===v)||(useRegEx && obj[i].toString().match(regExp))){if(Struct.wordReserved(i)||(!getFn && typeof obj[i]=='function')){continue;}r.key=i;r.value=obj[i];r.type=typeof obj[i];if(useRegEx){r.regExp=regExp.toString();}values.push(r);}if(typeof obj[i]=='object'){searchStruct(v, obj[i], useRegEx, regExp, getFn);}}};searchStruct(v, this, useRegEx, regExp, getFn);return values;};Struct.prototype.keyExists=function(k){return this.findKeys(k).length==0 ? false : true;};Struct.prototype.keyList=function(d){var delim=typeof d=='undefined' ? ',' : d;return this._keys.join(delim);};Struct.prototype.keyArray=function(){return this._keys;};Struct.prototype._setReservedWords=function(){for(i in this){if(i.substr(0, 1)=='_'||(typeof this[i]=='function' && this._searchArray(i, this._addedFunctions)==null)){this._reservedWords+=i+'|';}}this._reservedWords=this._reservedWords.substr(0, this._reservedWords.length-1);};Struct.prototype._dumpStyles=function(type, use){var r='';var table='font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;cell-spacing:2px;';var th='font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;text-align:left;color: white;padding: 5px;vertical-align :top;cursor:hand;cursor:pointer;';var td='font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;vertical-align:top;padding:3px;';var thScript='onClick="tTable(this);" title="click to collapse"';var tdScript='onClick="tRow(this);" title="click to collapse"';switch(type){case 'string':case 'number':case 'boolean':case 'undefined':case 'object':switch(use){case 'table':r=' style="'+table+'background-color:#0000cc;"';break;case 'th':r=' style="'+th+'background-color:#4444cc;"'+thScript;break;case 'td-key':r=' style="'+td+'background-color:#ccddff;cursor:hand;cursor:pointer;"'+tdScript;break;case 'td-value':r=' style="'+td+'background-color:#fff;"';break;}break;case 'array':switch(use){case 'table':r=' style="'+table+'background-color:#006600;"';break;case 'th':r=' style="'+th+'background-color:#009900;"'+thScript;break;case 'td-key':r=' style="'+td+'background-color:#ccffcc;cursor:hand;cursor:pointer;"'+tdScript;break;case 'td-value':r=' style="'+td+'background-color:#fff;"';break;}break;case 'function':switch(use){case 'table':r=' style="'+table+'background-color:#aa4400;"';break;case 'th':r=' style="'+th+'background-color:#cc6600;"'+thScript;break;case 'td-key':r=' style="'+td+'background-color:#fff;cursor:hand;cursor:pointer;"'+tdScript;break;case 'td-value':r=' style="'+td+'background-color:#fff;"';break;}break;case 'arguments':switch(use){case 'table':r=' style="'+table+'background-color:#dddddd;cell-spacing:3;"';break;case 'td-key':r=' style="'+th+'background-color:#eeeeee;color:#000000;cursor:hand;cursor:pointer;"'+tdScript;break;}break;}return r;};Struct.prototype._updateKeys=function(){this._keys=null;this._addedFunctions=null;this._keys=[];this._addedFunctions=[];var i;var allKeys=this.findValue('.*', true, true);for(i=0;i < allKeys.length;i++){this._keys.push(allKeys[i].key);if(allKeys[i].type=='function'){this._addedFunctions.push(allKeys[i].key);}}};Struct.prototype._parsePath=function(s){var a=s.split('.');var r=[];var re=/\[["']?(.+?)["']?\]/g;var i;var j;for(i=0;i < a.length;i++){j=0;while(t=re.exec(a[i])){if(j < 1){r.push(a[i].match(/(^.*?)\[/i)[1]);}r.push(t[1]);j++;}if(j < 1){r.push(a[i]);}}return r;};Struct.prototype._deleteArrayItem=function(k, a){var findKey=this._searchArray(k, a);if(findKey !=null){a.splice(findKey.pos, 1);}};Struct.prototype._searchArray=function(v, a){var i;for(i=0;i < a.length;i++){if(a[i]==v){var r={};r.value=a[i];r.pos=i;return r;}}return null;};Struct.prototype._isArray=function(a){return typeof a=='object' && a.constructor==Array;};Struct.prototype._returnBoolean=function(v){switch(v){case true:case 'true':case 'yes':case 1:return true;case false:case 'false':case 'no':case 0:return false;default:return false;}};Struct.prototype._handleError=function(e){var errorHtml='';var i;if(this._errorHandling){errorHtml+='<p><b>An error occurred, details are below</b></p><ul>';for(i in e){errorHtml+='<li><b>'+i+'</b> '+e[i]+'</li>';}errorHtml+='</ul>';this._openStructWindow('errorWin', 500, 500, errorHtml, 'An error occured...');}};Struct.prototype._identifyBrowser=function(){var agent=navigator.userAgent.toLowerCase();if (typeof window.opera != 'undefined'){return 'opera';} else if (typeof document.all != 'undefined'){if (typeof document.getElementById != 'undefined'){var browser = agent.replace(/.*ms(ie[\/ ][^ $]+).*/, '$1').replace(/ /, '');if(typeof document.uniqueID != 'undefined') {if (browser.indexOf('5.5') != -1){return browser.replace(/(.*5\.5).*/, '$1');}else{return browser.replace(/(.*)\..*/, '$1');}}else{return 'ie5mac';}}}else if(typeof document.getElementById != 'undefined'){if (navigator.vendor.indexOf('Apple Computer, Inc.')!=-1) {return 'safari';}else if(agent.indexOf('gecko')!=-1) {return 'mozilla';}}return false;};Struct.prototype._openStructWindow=function(winName, w, h, html, title, script){var leftPos=screen.width ?(screen.width-w)/ 2 : 0;var topPos=screen.height ?(screen.height-h)/ 2 : 0;var settings='height='+h+',width='+w+',top='+topPos+',left='+leftPos+',scrollbars=yes,menubar=yes,status=yes,resizable=yes';var browser=this._identifyBrowser();try{winName=window.open('', winName, settings);if(browser=='opera'||browser.indexOf('ie')!=-1||browser=='ie5mac'||browser=='safari'){winName.document.write('<html><head><title> '+title+' </title><script type="text/javascript">'+script+'</script><head>');winName.document.write('<body>'+html+'</body></html>');}else{winName.document.body.innerHTML=html;winName.document.title=title;var ffs=winName.document.createElement('script');ffs.setAttribute('type', 'text/javascript');ffs.appendChild(document.createTextNode(script));winName.document.getElementsByTagName('head')[0].appendChild(ffs);}winName.focus();}catch(e){alert('An error occurred opening the window,'+' This is probably because of your browser\'s pop-up blocker.');}};
