/**
 * RuzeeBorders 0.9.1
 * (c) 2006 Steffen Rusitschka <steffen@rusitschka.de>
 *
 * RuzeeBorders is freely distributable under the terms of an MIT-style license.
 * For details, see http://www.ruzee.com/
 */

function rzCrSimpleBorder(rad){
  return new RuzeeBorder(rad,rad,rad,0,true,'000');
}

function rzCrShadowBorder(rad,smar,coShadowS){
  return new RuzeeBorder(rad,rad+smar*2,rad+smar,Math.round(smar/2),false,coShadowS);
}

function rzCrFadeBorder(rad){
  return new RuzeeBorder(1,rad,1,0,true,'.fade');
}

function rzCrGlowBorder(rad,gmar,coGlowS){
  return new RuzeeBorder(rad,rad+gmar,rad,0,true,coGlowS);
}

var rzCache={};

function RuzeeBorder(cr,sr,sp,ss,si,cs){

this.isIE=navigator.userAgent.toLowerCase().indexOf('msie')>=0
  && navigator.userAgent.toLowerCase().indexOf('opera')==-1;
this.isXHTML=/html\:/.test(document.getElementsByTagName('body')[0].nodeName);
this.isStrict=document.compatMode?document.compatMode!='BackCompat':false;
this.cornerRadius=cr?cr:6;
this.shadowRadius=sr?sr:18;
this.shadowPadding=sp?sp:14;
this.shadowShift=ss?ss:0;
this.simple=si?si:false;
this.coShadowS=cs?cs:'000';

this.setBgImg=function(e,x,y){
  if(!this.imgBgInURL) return;
  e.style.backgroundImage=this.imgBgInURL;
  x=-x;y=-y;
  e.style.backgroundPosition=x+'px '+y+'px';
  if(this.imgBgInRepeat) e.style.backgroundRepeat=this.imgBgInRepeat;
};

this.crDiv=function(w,h,bg,o){
  var d=this.isXHTML
    ?document.createElementNS('http://www.w3.org/1999/xhtml','div')
    :document.createElement('div');
  d.style.padding=d.style.margin='0px';
  d.style.display='block';
  d.style.border='none';
  d.style.width=w?w:'auto';
  if(h) { d.style.height=h; d.style.fontSize=h; }
  if(!bg) bg='transparent';
  d.style.background=bg;
  if(o) d.style.overflow=o;
  return d;
}

this.addLRC=function(c,co,w,h,bgx,bgy){
  var e=this.crDiv(null,h,co);
  if(typeof bgx!='undefined') this.setBgImg(e,bgx,bgy);
  if(!w) w='1px';
  c.style.margin='0px '+(this.isR?w:'0px')+' 0px '+(this.isL?w:'0px');
  e.appendChild(c);
  return e;
}

this.flt=function(e,f){
  e.style.cssFloat=e.style.styleFloat=f;
}

this.crTB=function(top){
  var ca=rzCache[this.cacheID+'.'+top];
  if(ca){
    if(top) this.psT=ca.ps; else this.psB=ca.ps;
    return ca.el.cloneNode(true);
  }
  var sh=top?-this.shadowShift:this.shadowShift;
  var cxc=this.shadowPadding-this.cornerRadius-1;
  var cxb=cxc;
  var cxe=cxc+this.cornerRadius;
  var exb=0;
  var exe=cxc-1;
  var syc=this.cornerRadius-this.shadowPadding+sh+1;
  var yb,ye;
  if(top){
    if(!this.isT){
      this.psT=0;
      return;
    }
    yb=syc+this.shadowRadius-1;
    ye=syc-1;
    yi=-1;
    this.inSh=syc;
    this.psT=yb-ye;
  }else{
    if(!this.isB) {
      this.psB=0;
      return;
    }
    yb=syc<0?syc:0;
    ye=syc+this.shadowRadius;
    yi=1;
    this.psB=ye-yb;
  }
  var cwb=this.wBorder;
  if(cwb==0) cwb=1;

  var e=this.crDiv(null, Math.abs(yb-ye)+'px');
  for(var y=yb; y!=ye; y+=yi){
    var co;
    if(y<=this.cornerRadius-cwb){
      co=this.coBgIn;
    }else if(y<=this.cornerRadius){
      co=this.coBorder;
    }else if(y-syc<0){
      co=this.coShadow;
    }else{
      co=rzBlend(this.coShadow,this.coBgOut,(y-syc)/this.shadowRadius);
    }
    var line=this.crDiv(null,'1px',rzC2S(co),'hidden');
    var fstLine=line;
    var xbg=null;
    for(var x=0; x<this.shadowRadius; ++x){
      var isIn=false, setBgImg=false;
      var sd, out=0;
      if(y<syc){
        sd=x;
      }else{
        sd=Math.sqrt(Math.sqr(x)+Math.sqr(y-syc));
      }
      if(this.shadowRadius>this.cornerRadius && sd<=this.shadowRadius){
        co=rzBlend(this.coShadow, this.coBgOut, sd/this.shadowRadius);
      }else{
        co=this.coBgOut;
        out++;
      }
      if(y<=this.cornerRadius){
        if(x>=exb && x<=exe){
          if(y>this.cornerRadius-cwb){
            co=this.coBorder;
          }else{
            isIn=true;
          }
        }else if(x>=cxb && x<=cxe){
          var cd=Math.sqrt(Math.sqr(x-cxc)+Math.sqr(y))-this.cornerRadius;
          if(y<0){
            if(x-cxc>this.cornerRadius-this.wBorder){
              co=this.coBorder;
            }else{ 
              isIn=true;
            }
          }else if(cd<-cwb){
            isIn=true;
          }else if(cd<-cwb+1){
            // first on border! do bgimg
            if(top&&this.imgBgInURL){
//               xbg=this.shadowRadius-x;
//               this.setBgImg(line,this.shadowRadius-x,yb-y);
              setBgImg=true;
            }else
              co=rzBlend(this.coBgIn,this.coBorder,cd+cwb);
          }else if(cd<0){
            co=this.coBorder;
          }else if(cd<=1){
            co=rzBlend(this.coBorder,co,cd);
          }else{
            out++;
          }
        }
      }else{
        out++;
      }
      if(!isIn&&line==fstLine&&y<=this.cornerRadius-cwb&&top){
        this.setBgImg(fstLine,this.shadowRadius-x,yb-y);
      }
      if(out>1){
        line=this.addLRC(line,'transparent',(this.shadowRadius-x)+'px');
        x=this.shadowRadius; // done
      }else{
        if(!isIn){
          // fix a strange IE bug where the 12ths recursion seems to get lost...
          if(this.isIE&&x==this.shadowRadius-12) line=this.addLRC(line);
          line=this.addLRC(line,rzC2S(co));
        }
        if(setBgImg) this.setBgImg(line,this.shadowRadius-x,yb-y+1);
      }
    }
    e.appendChild(line);
  }
  rzCache[this.cacheID+'.'+top]={ el:e, ps:top?this.psT:this.psB };
  return e;
}


this.crLRC=function(e){
  var coBgInS=rzC2S(this.coBgIn);
  var coBS=rzC2S(this.coBorder);
  if(this.wBorder>0) e=this.addLRC(e,coBS,this.wBorder+'px');
  for(var x=this.shadowPadding; x<this.shadowRadius; ++x){
    coS=rzC2S(rzBlend(this.coShadow,this.coBgOut,x/this.shadowRadius));
    e=this.addLRC(e,coS);
  }
  return e;
}

this.setPad=function(d,s,l,subPx){
  padL='padding-'+l;
  borL='border-'+l+'-width';
  var pad=rzGetStyle(s,padL);
  var bor=rzGetStyle(s,borL);

  var v=rzPX2I(pad)+rzPX2I(bor)-subPx;
  d.style[rzCC(padL)]=(v<0?0:v)+'px';
}

this.draw=function(e,edges){
  if(e && (typeof e=='string')) {
    if(e.charAt(0)=='.'){
      e=RUZEE.getElementsByClass(e.substr(1));
    }else{
      e=document.getElementById(e);
    }
  }
  if(!e) return;
  if(e.constructor==Array){
    for(var i=0; i<e.length; ++i){
      this.draw(e[i],edges);
    }
    return;
  }
  var ed='lrtb';
  if(edges) ed=edges.toLowerCase();
  this.isL=ed.indexOf('l')>=0;
  this.isR=ed.indexOf('r')>=0;
  this.isT=ed.indexOf('t')>=0;
  this.isB=ed.indexOf('b')>=0;
  this.inSh=0;

  // Get the bg image
  this.imgBgInURL=rzGetStyle(e,'background-image',false,null);
  if(this.imgBgInURL&&this.imgBgInURL=='none') this.imgBgInURL=null;
  if(this.imgBgInURL){
    this.imgBgInRepeat=rzGetStyle(e,'background-repeat',false,null);
  }
  this.coBgIn=rzS2C(rzGetStyle(e,'background-color'),'#ffffff');
  this.coBgOut=rzS2C(rzGetStyle(e.parentNode,'background-color'),'#ffffff');
  var borderCSS='border-'+(this.isT?'top-':'bottom-');
  var bs=rzGetStyle(e,borderCSS+'style',false,'none');
  if(bs && bs!='' && bs!='none' && bs!='hidden'){
    this.coBorder=rzS2C(rzGetStyle(e,borderCSS+'color',false,'black'));
    this.wBorder=rzPX2I(rzGetStyle(e,borderCSS+'width',false,'1px'));
  }else{
    this.coBorder=this.coBgIn;
    this.wBorder=0;
  }
  this.coShadow=this.coShadowS=='.fade'?this.coBorder:rzS2C(this.coShadowS);

  this.cacheID=
    rzC2S(this.coBgIn)+'.'+rzC2S(this.coBgOut)+'.'+
    rzC2S(this.coBorder)+'.'+rzC2S(this.coShadow)+'.'+
    this.wBorder+'.'+this.isL+this.isR+this.isT+this.isB+'.'+
    this.cornerRadius+'.'+this.shadowRadius+'.'+
    this.shadowPadding+'.'+this.shadowShift+'.'+this.simple+'.'+
    this.imgBgInURL+'.'+this.imgBgInRepeat;

  var wr=this.crDiv();
  var cwr=this.crDiv(/*null,null,null,'hidden'*/);

  this.psT=0;
  this.psB=0;
  if(this.isT) wr.appendChild(this.crTB(true));
  wr.appendChild(this.crLRC(cwr));
  if(this.isB) wr.appendChild(this.crTB(false));
  var psLR=this.shadowRadius-this.shadowPadding+this.wBorder;
  var psL=this.isL?psLR:0;
  var psR=this.isR?psLR:0;
  var psT=Math.floor((this.psT+this.psB+this.inSh)/2);
  var psB=Math.floor((this.psT+this.psB+this.inSh+1)/2); // +1 for rounding

  var cwrbg=cwr;
  // lift the inner div up if necessary
  if(!this.simple&&this.inSh!=0){
    var up1=this.crDiv(); cwr.appendChild(up1);
    var up2=this.crDiv(); up1.appendChild(up2);
    cwr.style.position=up1.style.position='relative';
    up1.style.top=up2.style.marginBottom=this.inSh+'px';
    if(this.isIE) cwr.style.height='1%';
    cwrbg=up1; cwr=up2;
  }

  this.setPad(cwr,e,'top',psT);
  this.setPad(cwr,e,'bottom',psB);
  this.setPad(cwr,e,'left',psL);
  this.setPad(cwr,e,'right',psR);
  this.setBgImg(cwrbg,psL,this.psT+this.inSh);
  cwrbg.style.backgroundColor=rzC2S(this.coBgIn);

  if(this.isIE) e.style.height=cwr.style.height='1%'; // fix IE 3px jog when floated
  e.style.padding='0px';
  e.style.border='none';
  e.style.background='transparent';
  e.style.backgroundImage='none';
  e.appendChild(wr);

  while (e.childNodes.length>1){
    cwr.appendChild(e.removeChild(e.childNodes[0]));
  }
}
} // of RuzeeBorder

// internal tools

Math.sqr=function(x){
  return x*x;
}

function rzCC(s){
  for(var exp=/-([a-z])/; exp.test(s); s=s.replace(exp,RegExp.$1.toUpperCase()));
  return s;
}

function rzGetStyle(e,a,transOk,d){
  if(e==null) return d;
  if(typeof e=='string') e=document.getElementById(e);
  var v;
  if(document.defaultView){
    var cs=document.defaultView.getComputedStyle(e,null);
    if (!cs && window.getComputedStyle) cs=window.getComputedStyle(e,null);
    if(cs){
      v=cs.getPropertyValue(a);
      if(!v && cs.getPropertyCSSValue){
        v=cs.getPropertyCSSValue(a);
        if(v) v=v.getStringValue();
      }
    }
  }

  if(!v && e.currentStyle){
    v=e.currentStyle[rzCC(a)];
    if (!v) v=e.currentStyle[a];
  }

  if(!v && e.style) v=e.style[rzCC(a)];
  // KHTML bug fix: transparent is #000000 - if you want black, use #010101 in your CSS.
  // Safari work around: transparent is 'rgba(0, 0, 0, 0)'
  if(!transOk && v && (v.toLowerCase()=='transparent' || v=='#000000' || v=='rgba(0, 0, 0, 0)')) v=null;
  return v?v:d?d:e==document.body?d:rzGetStyle(e.parentNode,a);
}

function rzPX2I(px){
  if(!px) return 0;
  var p=/\s*(\d\d*)px/.exec(px);
  if(p) return parseInt(p[1]);
  return 0;
}

function rzS2C(s,d){
    if (!s) return d?rzS2C(d):[0,0,0,0];
    if (s.charAt(0)=='#') s=s.substr(1,6);
    s=s.replace(/ /g,'').toLowerCase();
    // The CSS 2.1 colors
    var COLORS = {
         aqua:'00ffff', black:'000000', blue:'0000ff', fuchsia:'ff00ff',
         gray:'808080', green:'008000', lime:'00ff00', maroon:'800000',
         navy:'000080', olive:'808000', orange:'ffa500', purple:'800080',
         red:'ff0000', silver:'c0c0c0', teal:'008080', white:'ffffff',
         yellow:'ffff00'
    };
    for (var key in COLORS) if (s==key) s=COLORS[key];

    var p=/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(s);
    if(p) return [parseInt(p[1]),parseInt(p[2]),parseInt(p[3]),parseInt(p[4])];
    var p=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(s);
    if(p) return [parseInt(p[1]),parseInt(p[2]),parseInt(p[3]),255];
    p=/^(\w{2})(\w{2})(\w{2})$/.exec(s);
    if(p) return [parseInt(p[1],16),parseInt(p[2],16),parseInt(p[3],16),255];
    p=/^(\w{1})(\w{1})(\w{1})$/.exec(s);
    if(p) return [parseInt(p[1]+p[1],16),parseInt(p[2]+p[2],16),parseInt(p[3]+p[3],16),255];
    return d?rzS2C(d):[0,0,0,0];
}

function rzC2S(c){
  if(typeof c=='string') return c;
  r='0'+c[0].toString(16);
  g='0'+c[1].toString(16);
  b='0'+c[2].toString(16);
  return '#'
    +r.substring(r.length-2)
    +g.substring(g.length-2)
    +b.substring(b.length-2);
}

function rzBlend(a,b,w){
  return Array(
    Math.round(a[0]+(b[0]-a[0])*w),
    Math.round(a[1]+(b[1]-a[1])*w),
    Math.round(a[2]+(b[2]-a[2])*w),
    Math.round(a[3]+(b[3]-a[3])*w));
}

// DEPRECATED STUFF - WILL BE REMOVED IN ONE OF THE NEXT RELEASES!

function rzGetElementsByClass(c,n,t) {
  return RUZEE.getElementsByClass(c,t);
}
