/*
*/

YajaxCheckException = function(problem,spec) {
    this.problem=problem
    this.spec=spec
}

YajaxCheckException.prototype.toString=function() {
    return "CheckException "+this.problem+':'+this.spec
}

YajaxException = function(msg,num) {
    this.msg=msg
    this.num=num
}
YajaxException.prototype.toString=function() {
    return ""+this.num+':'+this.msg
}


function Yajax() {
    if(!compatible) return
    this.submitClicked=false /* When true, this supresses the special
        handling of submit events */

    this.Qwait=null /* queue of waiting tasks */
    this.Qsent=null /* array of tasks sent and awaiting server response/time-out */
    this.Qtime=(new Date()).getTime(); /* last time server accessed.  Used for throttle. */
    this.QtimeoutId=null /* TimeOut object for server response time-out */
    this.QthrottleId=null /* TimeOut object for ending throttle-based wait */
    this.Qthrottle=false; /* Am I currently in throttle mode, intentionally not sending */
    this.Qxmlhttp=null /* the xmlhttprequest object */
    this.rf_rnd=''
    this.delayLocate=false
    this.findRules={}
    this.findRuleName={}
    this.shareCode={}

    eventHandler.addEvent(window, 'beforeunload', this.onbeforeunload)
    eventHandler.addEvent(document, 'click', this.defaultEventHandler)
    if(document.addEventListener) 
        eventHandler.addEvent(document, 'change', this.defaultEventHandler)
    else
        document.attachEvent('onfocusin',this.focusHack)
    eventHandler.addEvent(document, 'submit', this.onsubmit)
    eventHandler.addEvent(document, 'keypress', this.defaultEventHandler)
    

    this.touchCookie2();
    setInterval(this.touchCookie2,30000000)
    this.readCookie()
    this.readInst()
    this.isAJAX=true
    this.startArray=[]
}

Yajax.prototype.onStart=function() {
    for(var i=0;i<this.startArray.length;i++) {
        this.startArray[i]()
    }
}

Yajax.prototype.jsTest=function() {
    var y
    if(arguments.length>1) y=arguments[1]
    else y=false
    if(!arguments[0]) throw new YajaxCheckException('user',y);
}

function forceType(val,t) {
    if(t[0]==='*') {
        forceTypes(val,t.substr(1));
        return;
    }
    else {
        return forceType1(val,t);
    }
}

function forceType1(val,t) {
    if(!t) return val;
    t=t.substr(t.length-1)
    if((typeof val)=='undefined') val='UNDEFINED VALUE!';
    if(t=='s'||t=='S') return val.toString()
    if((typeof val)=='number'||val instanceof Number) {
        if(t=='f'||t=='g'||t=='F') return val 
        return(Math.floor(val))
    }
    if(val=='') return null
    val=val.toString()
    if(t=='x'||t=='X') return parseInt(val,16)
    if(t=='f'||t=='g'||t=='F') return parseFloat(val)
    if(t=='d') {
        val=val.toUpperCase()
        if(val=='T'||val=='TRUE') return 1
        if(val==''||val=='F'||val=='FALSE') return 0
        return parseInt(val,10)
    }
    alert("can't handle type '"+t+"'")
}

function formatOut(val,t) {
    var re=/^([^1-9fxXsSc.]*)(\d*)\.?(\d*)(\w)/
    var m=re.exec(t)
    var flags=m[1]
    var width=parseInt('0'+m[2],10)
    var format=m[4]
    var str,padder,padding
    var rj=flags.indexOf('-')==-1
    var padding, padder, i
    var sign=''
    if(format=='S') return ''+val

    if(rj&&flags.indexOf('0')!=-1) padder='0'
    else padder=' '

    if(val.toFixed&&m[3]!='') {
        var precision=parseInt(m[3],10)
        if(padder==' '||val>0) str=val.toFixed(precision)
        else {
            str=(-val).toFixed(precision)
            sign='-'
        }
    }
    else str=''+val;

    if(flags.indexOf('+')!=-1&&val>0) {
        if(padder==' ') str='+'+str
        else sign='+';
    }
    
    padding=''
    width-=sign.length+str.length
    for(i=0;i<width;i++) padding+=padder
    if(rj) str=sign+padding+str
    else str=sign+str+padding
    return str
}

function forceTypes(val,t) {
    for(i=0;i<val.length;i++) val[i]=forceType1(val,t);
}

Yajax.prototype.setValue=function() {
    var id,param
    var val=arguments[0]
    var e=arguments[1]
    if(e.id) {
        id=e.id;
        param=this.unEscapeYJID(id,false)
    }
    else {
        param=core.args(arguments)
        param=param.slice(1)
        id = this.escapeYJID(param)
        e=this.getElements(id)
        if(!e) alert('no such name/id '+id)
    }
    var baseId = param.shift()
    var rule=this.getRule(baseId)
    if(!rule) alert('no rule for '+baseId);
    if(!rule.type) alert('no type for '+baseId);
    val=formatOut(val,rule.type)
    this.setAttr(e,'value',val)
}

Yajax.prototype.getField=function(id) {
    var res=this.getAttr(id,'value')
    if(res) return res
    res=this.readParam(id)
    res=unescape(res)
    return res
}

Yajax.prototype.getValue=function() {
    var id,param
    var e=arguments[0]
    if(e.id) {
        id=e.id;
        param=this.unEscapeYJID(id,false)
    }
    else {
        id = this.escapeYJID(arguments)
        e=this.getElements(id)
        if(!e) alert('no such name/id '+id)
        param=core.args(arguments)
    }
    var baseId = param.shift()
    var rule=this.getRule(baseId)
    if(!rule) alert('no rule for '+baseId);
    var value=this.getAttr(e,'value')
    if(typeof(value)=='undefined') {
        //debug('getValue not found:',id)
        value=''
    }
    if(rule.type&&rule.type.substr(rule.type.length-1)=='s') alert('binary data is not supported with getValue');
    this.currentElement2=id
    this.currentValue2=value
    this.currentRule2=rule
    this.checkValue(rule,value)
    value = forceType1(value,rule.type)
    if(rule['test']) {
        var request=this.getRequestFromParam(rule,param)
        request.baseId=baseId
        request.value=value
        request.id=id
        request.element=e
        rule['test'].apply(rule,[yajax,request])
    }
    this.currentElement2=false
    this.currentValue2=false
    this.currentRule2=false
    return value
}

Yajax.prototype.getElements=function(n) {
    var e = document.getElementById(n)
    if(e&&e.id==n) return(e)
    e = document.getElementsByName(n)
    if(e.length==1) return e[0]
    return(e)
}

Yajax.prototype.setStyle=function(e,styles) {
    for(style in styles) {
        e.style[style]=styles[style] 
    }
}

Yajax.prototype.setMultiValue=function(a, value) {
    for(var i in a) {
        var e = a[i]
        if(typeof e.checked!='boolean') e.value = value
        else if(e.value==value) e.checked = false
        else e.checked = true
    }
}

Yajax.prototype.getAttr=function(a, attr) {
    if(typeof a=='string') a = this.getElements(a)
    if(a instanceof Array) {
        if(a.length==0) return ''
        if(attr!='value') return a[0][attr]
        for(i in a) {
            if(attr=='value'&&a.checked==true) return a.value
        }
        return ''
    }
    else {
        return a[attr] 
    }
}

Yajax.prototype.setAttr=function(a, attr, value) {
    if(typeof a=='string') a = this.getElements(a)
    var e;
    if(a instanceof Array) {
        if(attr=='value') this.setMultiValue(a, value)
        else { 
            for(i in a) {
                var e = a[i]
                if(attr=='style') this.setStyle(e, value)
                else e[attr]=value
            }
        }
    }
    else {
        e = a
        if(attr=='style') this.setStyle(e, value)
        else  e[attr]=value
    }
}

Yajax.prototype.setAttrs=function(a) {
    for(e in a) {
        var attrs = a[e]
        for(attr in attrs) {
            this.setAttr(e, attr, attrs[attr]) 
        }
   }
}

/* end of special server stuff */

Yajax.prototype.readParam=function(param) {
    var h=location.href
    var x=h.indexOf(param+'=')
    if(x==-1) return ''
    h=h.substring(h,x+1+param.length)
    x=h.indexOf('&')
    if(x==-1) return h;
    else return h.substring(0,x);
}

Yajax.prototype.readInst=function() {
    var h=location.href
    var x=h.indexOf('inst=')
    if(x==-1) return
    h=h.substring(h,x+5)
    x=h.indexOf('.')
    if(x==-1) return
    h=h.substring(0,x)
    this.instance=parseInt(h,16)
}

Yajax.prototype.readCookie=function() {
    var cookie
    if(arguments.length>0) cookie=arguments[0]
    else cookie=core.getCookie('yj1')
    if(!cookie) return

    if(!cookie.split) debug('cookie',cookie)
    cookie=cookie.split('-')
    this.rf_rnd=cookie[1]
    var c=cookie[3]
    if(!c||!c.indexOf) return
    var x=c.indexOf('.')
    c=c.substring(0,x)
    this.instance=parseInt(c,16)
    if(cookie[4]!='Y') {
        cookie[4]='Y'
        core.setCookie('yj1', cookie.join('-'), 0,'/')
    }
}

Yajax.prototype.touchCookie2=function() {
    if(arguments.length>0) cookie=arguments[0]
    else cookie=core.getCookie('yj2')
    if(!cookie||!cookie.split) return

    var l=cookie.split('-')
    l=parseInt(l[2],16)
    var d=new Date()
    var exp=Math.floor(d.getTime()/1000)
    exp+=l
    d.setTime(exp*1000)
    core.setCookie('yj2',cookie,d,'/')
}

/* Q stuff */

Yajax.prototype.pushQ=function(todo) {
// act/in rule e request
    var now=(new Date()).getTime()
    if(this.Qwait===null) this.Qwait=new Array()
    var Qwait=this.Qwait
    if(Qwait.length>0) {
        if(todo[0]=='in'&&Qwait[Qwait.length-1][0]=='in'&&
            todo[2]==Qwait[Qwait.length-1][2]&&
            todo[3].value==Qwait[Qwait.length-1][3].value
            )
            Qwait[Qwait.length-1]=todo
    }
    else Qwait[Qwait.length]=todo
    if(this.Qthrottle==false&&!this.Qsent) {
        if(now>this.Qtime+500) {
            this.Qtime=now
            this.deQ()
        }
        else {
        /* this creates a bit of a throttle.  If the user is hammering on some kind of event, then they
        are accumulated so that they can be handled more efficiently, even if the server can handle them all.*/
            this.QthrottleId=setTimeout(this.restartQ,5000)
            this.Qthrottle=true
        }
    }
    this.Qtime=now
}

Yajax.prototype.restartQ=function() {
    yajax.Qthrottle=false
    yajax.deQ()
}

Yajax.prototype.deQ=function() {
    if(this.Qthrottle==true) return
    if(this.Qsent) return
    if(!this.Qwait) {
        /* i'm idle */
        if(this.delayLocate) {
            if(this.delayLocate instanceof Array) {
                var f=this.delayLocate[0]
                if(this.delayLocate[1]) {
                    var inp=document.createElement('input')
                    inp.setAttribute('type','hidden')
                    inp.setAttribute('name',this.delayLocate[1])
                    inp.setAttribute('value','1')
                    f.appendChild(inp)
                }
                f.submit()
            }
            else location.href=this.delayLocate
        }
        return
    }
    yajax.readCookie()
    var str=this.rf_rnd+'\014'
    var Qwait=this.Qwait
    this.Qsent=Qwait
    this.Qwait=null
    if(yajax.yajaxCommon)
        str+=core.json_encode(yajax.yajaxCommon)
    str+='\014';
    for(var i=0;i<Qwait.length;i++) {
        // act/in rule e request
        var todo=Qwait[i]
        var pass=this.getPassServer(todo[1],todo[3])
        str += todo[2].id+'\012'
        str += core.json_encode(pass)+'\014'
    }
    // debug('sending ...'+str)
    this.Qxmlhttp=core.XMLHttpRequest()
    this.Qxmlhttp.onreadystatechange = this.reqReturn;
    var href=core.urlAdds(location.href,'yajax_req=y')
    var inst=yajax.readParam('inst')
    if(inst) href=href+'&inst='+inst
    this.Qxmlhttp.open('POST',href,true)
    this.Qxmlhttp.send(str)
    this.QtimeoutId=setTimeout(this.reqAbort,10000)
}

Yajax.prototype.reqAbort=function() {
    yajax.QtimeOutId=null;
    if(!yajax.Qxmlhttp) { yajax.deQ(); return; }
    if(yajax.Qxmlhttp.readyState==4) { yajax.deQ(); return; }
    yajax.Qxmlhttp.abort();    
    yajax.Qxmlhttp.onreadystatechange=null;
    if(!yajax.Qsent) { yajax.deQ(); return; }
    if(yajax.Qwait) yajax.Qwait=yajax.Qsent+yajax.Qwait;
    else yajax.Qwait=yajax.Qsent;
    yajax.Qsent=null;
    yajax.deQ();
    alert('server delay')
}


Yajax.prototype.reqReturn=function() {
    var Qxmlhttp=yajax.Qxmlhttp;
    if(Qxmlhttp.readyState!=4) return;
    Qxmlhttp.onreadystatechange=returnOne;
    if(yajax.QtimeoutId!==false) clearTimeout(yajax.QtimeoutId);
    if(Qxmlhttp.sent>=300||Qxmlhttp.sent<200) { 
        if(yajax.Qwait) yajax.Qwait=yajax.Qsent+yajax.Qwait;
        else yajax.Qwait=yajax.Qsent;
    }
    else {
        response=Qxmlhttp.responseText
        response=response.split('\014')
        if(response.length<4||response[0].substr(0)=='<'
            ||response[0].length>128) {
            response=response.join('\014')
            if(response.length>1000) 
                response=response.substr(response.length-1000)
            alert('server error: '+response)
            yajax.Qsent=null
            yajax.Qwait=null
            return
        }
        var cookie1=response[0]
        if(cookie1.length>0) {
            core.setCookie('yj1',cookie1,0,'/')
            yajax.readCookie(cookie1)
        }
        var cookie2=response[1] 
        if(cookie2.length>0) {
            if(cookie2=='0') core.delCookie('yj2')
            else yajax.touchCookie2(cookie2)
        }
        yajax.setAttrs(eval('('+response[2]+')'))
        yajax.yajaxCommon=eval('('+response[3]+')')
        var i
        for(i=4;i<response.length;i++) {
            var res=response[i]
            if(res[0]=='e') {
                res=eval('('+res.substr(1)+')')
                yajax.currentPhase=res[0]
                yajax.currentElement1=res[1]
                yajax.currentElement2=res[2]
                yajax.currentValue1=res[3]
                yajax.currentValue2=res[4]
                yajax.currentRule1=res[5]
                yajax.currentRule2=res[6]
                yajax.currentVariable=res[7]
                yajax.currentKey=res[8]
                yajax.handleComplaint(res[9],res[10])
                continue
            }
            res=eval('('+res+')')
            // act/in rule e request
            todo=yajax.Qsent[i-4]
            if(todo[1].after)
                todo[1].after.apply(todo[1],[yajax, 
                    todo[3], res]);
        }
    }
    yajax.Qsent=null
    yajax.deQ();
}

/* 
onbeforeunload is non-standard, so this might not be called.
*/
Yajax.prototype.onbeforeunload=function(ev) {
    var ev2 = new Event2(ev)
    if(yajax.Qsent||yajax.Qwait) {
        ev2.preventDefault();
        if(yajax.waiting) return yajax.waiting
        else return "Please try again in a moment. Do you wish to leave this page, even though you may lose your most recent changes?"
    }
}

Yajax.prototype.checkValue=function(rule,value) {
    if(rule['len']) {
        if(value.length>rule['len']) {
            yajax.complain('len',value.length)
        }
    }
    if(rule['regexp']) {
        if(!rule['regexp'].test(value)) {
            yajax.complain('regexp',rule['regexp'])
        }
    }
}

Yajax.prototype.checkElements=function(a) {
    for(var i in a) {
        this.getValue(a)
    }
}

Yajax.prototype.checkForm=function(id) {
    var f=document.getElementById(id)
    var es=f.elements
    var names={}
    for(var i=0;i<es.length;i++) {
        var e=es[i]
        if(e.id&&e.name&&e.type!='submit'&&e.type!='image'&&
            e.nodeName!='BUTTON') {
            if(e.name!=e.id) {
                if(!names[e.name]) {
                    names[e.name]=true
                    this.getValue(e.name)
                }
            }
            else this.getValue(e)
        }
    }
}

Yajax.prototype.forward=function() {
    var ref,explanation
    if(arguments.length>0) ref=arguments[0]
    else return
    if(!ref) return

    else if(ref.length>=5&&ref.substr(0,5)=='http:'||
        ref.length>=6&&ref.substr(0,6)=='shttp:');
    else if (ref.length>=1&&ref.substr(0,1)=='/') {
        debug('hn',location.hostname)
        ref=location.hostname+ref
    }
    else {
        var base=document.getElementsByTagName('base')
        if(base) base=base[0]
        if(base) base=base.href
        if(!base) base=location.href
        ref=core.calcPath(base,ref)
    }

    if(yajax.Qsent||yajax.Qwait) {
        yajax.delayLocate=ref
    }
    else location.href=ref
}

Yajax.prototype.onkeypress=function(rules, ev2) {
    var c;
    var ch=ev2.ch
    if(ch=='') return
    if(rules['chars']&&!rules['chars'].test(ch)) { 
        ev2.preventDefault(); 
        return; 
    }
    var value=ev2.target.value
    if(!ev2.target.maxlength) {
        if(rules['len']&&value.length>=rules['len']) {
            ev2.preventDefault();
        }
    }
}

Yajax.prototype.w3cIDencode=function(val) {
    val = encodeURIComponent(val)
    val = val.replace('/\\./g','.2e')
    val = val.replace('/!/g','.21')
    val = val.replace('/~/g','.7e')
    val = val.replace('/\'/g','.27')
    val = val.replace('/\\(/g','.28')
    val = val.replace('/\\)/g','.29')
    
    val = val.replace('/%/g','.')
    return val
}

Yajax.prototype.w3cIDdecode=function(val) {
    val = val.replace('/\\./g','%')
    val = decodeURIComponent(val)
    return val
}

Yajax.prototype.unEscapeYJID=function(str,types) {
    var args, i, t, out
    var fullResp=false,rule=false;
    if(types===true) {
        types=false;
        fullResp=true;
    }

    if(str instanceof Array) args=str 
    else args=str.split(':') 
    if(!types) {
        rule=this.getRule(args[0])
        if(!rule&&fullResp) return [args,false];
        if(!rule) alert('unknown id '+args[0])
        if(!rule['param']) types=new Array()
        else types=rule['param'][0]
    }
    for(i=1;i<args.length;i++) {
        t=types[i-1]
        out=args[i]
        if(t=='s');
        else if(t=='S') out=this.w3cIDdecode(out);
        else if(t===false&&out=='');
        else if(t===false&&out.substr(0,1)=='_') out=this.w3cIDdecode(out.substr(1)) 
        else out=parseInt(out,16)
        args[i]=out;
    }
    if(fullResp) return [args,rule]
    return args;
}

Yajax.prototype.getPassServer=function(rule,request) {
    if(!rule.passServer) return []
    var out=[]
    var pass=rule.passServer[1]
    for(var i=0;i<pass.length;i++) {
        out.push(request[pass[i]])
    }
    return out
}

Yajax.prototype.getRequestFromParam=function(rule,param) {
    var request={},i
    if(!rule.param) return request
    for(i=0;i<rule.param[1].length;i++) {
        request[rule.param[1][i]]=param[i]
    }
    return request
}


Yajax.prototype.getElement=function() {
    var a=arguments[0]
    if(arguments.length>1) var types=arguments[1];
    else var types=null
    return document.getElementById(this.escapeYJID(a,types))
}

Yajax.prototype.escapeYJID=function(a,types) {
    var i, t, str, val 
    var rule=false;
    if(a.length==1) return a[0];
    str=[]
    if(a.length>1&&!types) {
        rule=this.getRule(a[0])
        if(!rule) alert('No rule for '+a[0])
        types=rule['param'][0]
        if(!types) alert('no rule for escape')
    }
    str.push(a[0])
    for(i=1;i<a.length;i++) {
        t=types[i-1]
        val=a[i]
        val=forceType1(val,t)
        if((typeof val)=='string'||(val instanceof String)) {
            if(val=='') str.push('')
            else if(t=='s') str.push(val)
            else if(t) str.push(this.w3cIDencode(val))
            else str.push('_'+this.w3cIDencode(val))
        }
        else if((typeof val)=='boolean'||(val instanceof Boolean)) {
            if(val) str.push('1')
            else str.push('0')
        }
        else if((typeof val)=='number'||(val instanceof Number)) {
            str.push(val.toString(16).toUpperCase())
        }
        else alert("bad type for escape on '"+val+"'")
    }
    str=str.join(":")
    return str
}

Yajax.prototype.prepare=function(rule, id, 
    baseId, param, value, e) {
    var request=this.getRequestFromParam(rule,param)
    request.id=id
    request.baseId=baseId
    request.element=e
    this.currentPhase='test'
    this.currentElement1=e.id
    this.currentElement2=false
    this.currentValue1=value
    this.currentValue2=false
    this.currentRule1=baseId
    this.currentRule2=false
    this.currentVariable=false
    this.currentKey=false
    this.checkValue(rule,value)
    request.value=forceType1(value,rule.type)

    if(rule['test']) rule['test'].apply(rule,[yajax,request])
    if(rule['testedEvent']) {
        var ev2=eventHandler.ev2
        var ev=ev2.ev
        var res=rule['testedEvent'].apply(rule,[yajax,request,ev,ev2])
        if(res) return 0
    }
    if(rule['before']) rule['before'].apply(
        rule,[yajax,request])
    return request
}

Yajax.prototype.complain=function(problem,spec) {
    throw new YajaxCheckException(problem,spec)
}

Yajax.prototype.changeIt=function(rule,baseId,param,value,e) {
    var request=this.prepare(rule, e.id, baseId,param,value,e)
    if(request&&rule['server']) {
        yajax.pushQ(new Array('in',rule,e,request))
    }
}

Yajax.prototype.onchangetext=function(rule, baseId, param, ev2) {
    var target = ev2.target
    yajax.changeIt(rule, baseId, param, target.value, target)
}

Yajax.prototype.onchangebox=function(rule, baseId, param, ev2) {
    var target = ev2.target
    var value
    if(target.checked) value=target.value
    else value=''
    yajax.changeIt(rule, baseId, param, value, target)
}

Yajax.prototype.onclicklink=function(ev2) {
    var target = ev2.target
    var href=target.href
    if(ev2.ev.button>1) return
    if(!href) return // probably just a target
    /*if(yajax.instance&&
        href.substr(0,7)!='http://'&&
        href.substr(0,8)!='shttp://'&&
        href.indexOf('&inst=')==-1) {
            href=core.urlAdds(href,'inst='+yajax.instance)
    }*/
    if(yajax.Qsent||yajax.Qwait) {
        yajax.delayLocate=href
        ev2.preventDefault()
    }
    else location.href=href
}

Yajax.prototype.onclick=function(rule, baseId, param,ev2) {
    var target = ev2.target
    var request
    if(target.nodeName=='INPUT'&&(target.type=='submit'||target.type=='image')) {
        if(target.name) yajax.submitClicked=target.name
        else yajax.submitClicked=true
    }
    try {
        request=this.prepare(
            rule, target.id, baseId, param, true,target)
    } catch(e) {
        ev2.preventDefault()
        throw e
    }
    if(!request) {
        ev2.preventDefault() 
        return
    }
    if(!rule['loadPage']) {
        ev2.preventDefault() 
    }

    if(rule['server']&&!rule['loadPage']) {
        yajax.pushQ(new Array('act',rule,target,request))
    }
}

Yajax.prototype.getDefElement=function(form) {
    var a = document.getElementsByName('__yajax_def')
    var e
    for(var i=0;i<a.length;i++) {
        e=a[i]
        if(e.form===form) return e 
    }
    return(false)
}

Yajax.prototype.maybeDelayClick=function(ev2,form) {
    if(ev2.returnValue==true&&(this.Qsent||this.Qwait)) {
        if(this.submitClicked===true) 
            this.delayLocate=[form,false]
        else this.delayLocate=[form,this.submitClicked]
        ev2.preventDefault()
    }
    this.submitClicked=false
}

Yajax.prototype.onsubmit=function(ev) {
    var ev2=new Event2(ev)
    var target=ev2.target
    var form=target
    if(form.form) form=form.form
    var id,e=false,i
    if(yajax.submitClicked&&yajax.submitClicked!=true) {
        yajax.maybeDelayClick(ev2,form)
        return
    }
    
    e=yajax.getDefElement(form)
    if(e===false) return
    id=e.value
    if(!id||id==='') {
        yajax.submitClicked=false
        ev2.preventDefault()
        return
    }

    if(id.substr(0,1)=='1') {
        yajax.submitClicked=false
        ev2.preventDefault()
        return
    }

    id=id.substr(1)
    ev2.target=document.getElementById(id)

    var res=yajax.unEscapeYJID(id,true)
    var param=res[0]
    var baseId=param.shift()
    try {
        yajax.onclick(res[1],baseId,param,ev2);
    }
    finally {
        yajax.maybeDelayClick(ev2,form)
    }
}

Yajax.prototype.getRule=function(baseId) {
    return this.findRules[baseId]
}

Yajax.prototype.focusHack=function(ev) { /* MS Only */
    var ev2 = new Event2(ev)
    ev=ev2.ev
    var target = ev2.target
    if(target.yjchangeset) return

    var id=target.id
    var res=yajax.unEscapeYJID(id,true)
    var rule=res[1]

    if(!rule) return 

    if(!rule['e']) rule['e'] = getClosure(yajax.handleYjEvent, rule, false)

    target.attachEvent('onchange',rule['e'])
    target.yjchangeset=1
}

Yajax.prototype.defaultEventHandler=function(ev) {
    var ev2 = new Event2(ev)
    ev=ev2.ev
    var target = ev2.target
    var id=target.id
    if(id) {
        var res=yajax.unEscapeYJID(id,true)
        var params=res[0]
        var rule=res[1]

        var baseId = params[0]
    }
    if(!id||!rule) {
        if(yajax.userEvent) {
            if(yajax.userEvent(ev,ev2)) {
                ev2.preventDefault()
            }
        }
        if(ev.type=='click'&&ev2.returnValue&&target.nodeName=='A') yajax.onclicklink(ev2)
        return
    }

    if(!rule['e']) 
        rule['e'] = getClosure(yajax.handleYjEvent, rule, false)

    yajax.handleYjEvent(rule, params, ev)
    eventHandler.addEvent(target, ev.type, rule['e'])
}

Yajax.prototype.fakeEvent=function(ev) {
    var id=ev.target.id
    var res=yajax.unEscapeYJID(id,true)
    var params=res[0]
    var rule=res[1]
    this.handleYjEvent(rule,params,ev)
}

Yajax.prototype.handleYjEvent=function(rule, paramAndBase, ev) {
    ev2 = new Event2(ev)
    ev=ev2.ev
    ev2.stopPropagation()
    var target=ev2.target
    
    if(ev.type=='click'&&(target.type=='text'||target.type=='password'||target.type=='checkbox'||target.nodeName=='TEXTAREA'||target.nodeName=='SELECT')) return;

    if(!target.id) return /* can happen if event bubbled up
    from sub-element, such as an option can bubble up to its
    select */

    if(ev.type=='keypress') return yajax.onkeypress(rule, ev2)
    try {
        if(!paramAndBase) paramAndBase = yajax.unEscapeYJID(target.id,rule.param)
        var baseId = paramAndBase.shift()
        var param = paramAndBase
        if(rule.userEvent) {
            if(rule.userEvent(yajax,baseId,param.slice(),
                ev,ev2)) return
        }
        if(ev.type=='change') {
            if(target.type=='checkbox')
                return yajax.onchangebox(rule, baseId, param, ev2)
            else 
                return yajax.onchangetext(rule, baseId, param, ev2)
        }
        else if(ev.type=='click') {
            yajax.onclick(rule, baseId, param, ev2)
            if(target.nodeName=='A'&&ev2.returnValue) 
                yajax.onclicklink(ev2)
        }
    }
    catch(e) {
        if(e instanceof YajaxCheckException) {
            yajax.handleComplaint(e.problem,e.spec)
        }
        else throw(e)
    }
}


Yajax.prototype.ruleP=function(rule) {
    return rule.param[0][0]
}

function testAJAX(ifID,ifNotID) {
    elIf=document.getElementById(ifID)
    elIfNot=document.getElementById(ifNotID)
    if(compatible) {
     //   elIf.style.display='visible'
        elIfNot.style.display='none'
    }
}

yajax=new Yajax()

