<?xml version="1.0" encoding="UTF-8" ?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at
  
      http://www.apache.org/licenses/LICENSE-2.0
    	  
  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
  
-->
<library>

<class name="sharedObject" extends="node">

	<attribute name="so" value="null" />
	<attribute name="onStatus" value="null" />
	

	<method name="connect" args="so_Name,nc,persistant">

		//Debug.write("connect SharedObject: ",nc.uri);
		this.so = SharedObject.getRemote(so_Name,nc.uri,persistant); 
		
		var t = this;
		this.so.onSync = function (evtObj){
			if (t.onStatus)t.onStatus.sendEvent(evtObj);
			//_root.Debug.write.write("Shared Object onSync",evtObj,arguments);
		}
		
		this.so.connect(nc);
		
	</method>
	
    
    <method name="getRemote" args="so_Name,nc,persistant">

        //Debug.write("connect SharedObject: ",nc.uri);
        this.so = SharedObject.getRemote(so_Name,nc.uri,persistant); 

        var t = this;
        this.so.onSync = function (evtObj){
            if (t.onStatus)t.onStatus.sendEvent(evtObj);
            //_root.Debug.write.write("Shared Object onSync",evtObj,arguments);
        }
    </method>
    
    <!--- create Object if not existing  -->
    <method name="getLocal" args="name">

        this.so = SharedObject.getLocal(name); 

        var t = this;
        this.so.onSync = function (evtObj){
            if (t.onStatus)t.onStatus.sendEvent(evtObj);
            //_root.Debug.write.write("Shared Object onSync",evtObj,arguments);
        }
        
    </method>
    
    <!--- 
        force write to disk
        @return true(success) false(User has forbidden to store data local)
      -->
    <method name="flush">
        return this.so.flush();
    </method>

    <method name="getData" args="key">
        if (this.so.data["key"] == undefined){
            return null;
           //_root.Debug.write.write("key undefined",key);
        } else {
            return this.so.data["key"];
        }
    </method>
	
    <method name="setData" args="key,val">
    	//Debug.write("this...... so: ",this.so);
        this.so.data["key"] = val;
    </method>

		
</class>

</library>
