var MAX_NUM_COOKIES=20;
var MAX_COOKIE_SIZE=4096;
var ENCODE_SIZE=3;
var COOKIE_EXPIRE=1;

function JSDBO(dbname)
{
    // private variables
    var jsdbname=dbname;
    var containerValues=new Array();
    var UID=getUserID();
    jsdboGetCookie(jsdbname);
    this.setValue=jsdboSetValue;
    this.getValue=jsdboGetValue;
    this.deleteValue=jsdboDeleteValue;
    this.getDBName=jsdboGetDBName;
    this.isAvailable=jsdboIsAvailable;
    this.size=jsdboSize;
    this.keys=jsdboKeys;
    this.commit=jsdboCommit;
    this.drop=jsdboDrop;
    this.truncate=jsdboTruncate;
    this.clone=jsdboClone;
    this.userID=UID;

    // private methods
    function jsdboCreateCookie(name,value,days)
    {
        if(days)
        {
            var date=newDate();
            date.setTime(date.getTime()+(days*24*60*60*1000));
            var expires=";expires="+date.toGMTString();
        }
        else
        {
            var expires="";
        }
        document.cookie=name+"="+value+expires+";path=/";
    }

    function jsdboSetCookie(c_name,value,expiredays)
    {
        var exdate=new Date();
        exdate.setDate(exdate.getDate()+expiredays);
        document.cookie=c_name+"="+escape(value)+((expiredays==null)?"":";expires="+exdate.toGMTString())+";path=/";
    }

    function jsdboGetCookie(c_name)
    {
        var cVals='';
        if(document.cookie.length>0)
        {
            c_start=document.cookie.indexOf(c_name+"=");
            if(c_start!=-1)
            {
                c_start=c_start+c_name.length+1;
                c_end=document.cookie.indexOf(";",c_start);
                if(c_end==-1)
                {
                    c_end=document.cookie.length;
                }
                cVals=unescape(document.cookie.substring(c_start,c_end));
            }
        }

        var keysAndVals=cVals.split(";");
        for ( i = 0; i < keysAndVals.length; i++ )
        {
            if ( keysAndVals[i].length > 0 )
            {
                var keyVal=keysAndVals[i].split(":");
                containerValues[keyVal[0]]=keyVal[1];
            }
        }
    }

    function deleteJSDBO()
    {
        containerValues=null;
        jsdbname=null;
        UID=null;
        this.setValue=null;
        this.getValue=null;
        this.deleteValue=null;
        this.getDBName=null;
        this.isAvailable=null;
        this.size=null;
        this.keys=null;
        this.commit=null;
        this.drop=null;
        this.truncate=null;
        this.clone=null;
    }

    // public methods
    function jsdboSetValue(name,value)
    {
        containerValues[name]=value;
    }

    function jsdboGetValue(name)
    {
        return containerValues[name];
    }

    function jsdboDeleteValue(name)
    {
        if(containerValues[name])
        {
            containerValues[name]=null;
            return 1;
        }
        return 0;
    }

    function jsdboGetDBName()
    {
        return jsdbname;
    }

    function jsdboIsAvailable()
    {
        if(document.cookie.split(";").length<MAX_NUM_COOKIES)
        {
            return true;
        }
        return false;
    }

    function jsdboSize()
    {
        var size=0;
        for(keyName in containerValues)
        {
            if(keyName)
            {
                if(containerValues[keyName]!=null)
                {
                    size+=escape(keyName).length+ENCODE_SIZE+escape(containerValues[keyName]).length+ENCODE_SIZE;
                }
            }
        }
        return size;
    }

    function jsdboKeys()
    {
        var keys=new Array();
        for(keyName in containerValues)
        {
            if(containerValues[keyName]!=null)
            {
                keys.push(keyName);
            }
        }
        return keys;
    }

    function jsdboCommit()
    {
        var data='';
        if(jsdboSize()<MAX_COOKIE_SIZE)
        {
            for(keyName in containerValues)
            {
                if(keyName)
                {
                    if(containerValues[keyName]!=null)
                    {
                        data+=keyName+":"+containerValues[keyName]+";";
                    }
                }
            }
            jsdboSetCookie(jsdbname,data,COOKIE_EXPIRE);
        }
        else
        {
            alert("Maximum cookie size exceeded,values not written.");
        }
    }

    function jsdboDrop()
    {
        jsdboSetCookie(jsdbname,"",-1);
        deleteJSDBO();
    }

    function jsdboTruncate()
    {
        jsdboSetCookie(jsdbname,"",COOKIE_EXPIRE);
        containerValues=new Array();
    }

    function jsdboClone(cdbname)
    {
        var myNewObj=new JSDBO(cdbname);
        for(var keyName in containerValues)
            myNewObj.setValue(keyName,containerValues[keyName]);
        myNewObj.commit();
        return myNewObj;
    }

    function getUserID()
    {
        var c_name="user_id";
        var userID='';
        if(document.cookie.length>0)
        {
            c_start=document.cookie.indexOf(c_name+"=")
            if(c_start!=-1)
            {
                c_start=c_start+c_name.length+1
                c_end=document.cookie.indexOf(";",c_start)
                if(c_end==-1)c_end=document.cookie.length
                userID=unescape(document.cookie.substring(c_start,c_end))
            }
        }
        return userID;
    }
}
