﻿// FreeStyler Library // Copyright 2009 Ian Porter

function fsStyleVar(parentElement,style,varName,varValue)
{
    this.parentElement = parentElement;
    this.style = style;
    varName = varName.replace(" ","");
    varValue = varValue.replace(" ","");
    this.varName = fsGetVarName(varName);
    varValue = fsConvertAnyHexToRgb(varValue);

    this.endNumbers =  varValue.match(this.pattNumber);
    this.template = varValue.replace(this.pattNumber ,"#number#");
    //alert("name:" + this.varName +"\nend:" +  varValue + "\ntemplate:"+this.template+"\nnumbers:"+this.endNumbers);
}

fsStyleVar.prototype.pattNumber = /[\+\-\d.]+/g;

fsStyleVar.prototype.init = function()
{
    this.startValue = this.parentElement ?
        fsGetComputedStyle(this.parentElement,this.varName) // get cascaded style from element
        : eval("this.style."+this.varName);                 // get style from rule
    if(this.startValue)
        this.startNumbers = fsConvertAnyHexToRgb(this.startValue).match(this.pattNumber);
    else
        fsError.log("Missing start value for: " + this.varName);
    //alert("name:" + this.varName +"\nstart:" + this.startValue + "\ntemplate:"+this.template+"\nnumbers:"+this.startNumbers);
}

fsStyleVar.prototype.step = function(scaler)
{
    //alert("style."+this.varName+" "+this.template); 
    var newValue;
    if(this.startNumbers)
    {
        // numeric styles
        newValue = this.template;
        for (j=0;j<this.startNumbers.length;j++)
        {
            var val = this.startNumbers[j] - (this.startNumbers[j]-this.endNumbers[j]) * scaler;
            val = val.toFixed( this.varName.toLowerCase().search("color")>=0 ? 0:3 );  // colours must to be integers
            newValue = newValue.replace(/#number#/, val );
        }
        newValue = fsConvertAnyRgbToHex(newValue);    // IE likes hex colours
    }
    else
    {
        // non-numeric, only apply change at end
        if(scaler==1.0)
            newValue = this.template;
        else
            newValue = this.startValue;
        // special case for display:none
        if(this.varName=="display" && this.startValue=="none" && scaler>0.0)
            newValue = this.template;
    }

    if(newValue && newValue!=undefined)
        try { 
            //alert("style."+this.varName+" = "+newValue); 
            eval("this.style."+this.varName+" = newValue"); } 
        catch(ex){ 
            fsError.log(ex); }
}

function fsGetVarName(str)
{
    str = str.toLowerCase();
    while( (pos = str.indexOf("-")) > 0 )
        str = str.substring(0,pos) + str.charAt(pos+1).toUpperCase() + str.substr(pos+2);
    return str;    
}

function fsConvertAnyHexToRgb(hexStr)
{
    var colours =  hexStr.match(/(#[\dabcdef]{6})|(#[\dabcdef]{3})/gi);
    if(colours)
        for (var i=0;i<colours.length;i++)
        {
            var len = (colours[i].length-1)/3;
            var r = parseInt(colours[i].substr(1,len),16);
            r = len==2 ? r : r*17;
            var g = parseInt(colours[i].substr(1+len,len),16);
            g = len==2 ? r : g*17;
            var b = parseInt(colours[i].substr(1+len*2,len),16);
            b = len==2 ? b : b*17;
            hexStr = hexStr.replace(/(#[\dabcdef]{6})|(#[\dabcdef]{3})/i ,"rgb("+r+","+g+","+b+")");
        }
    return hexStr;
}

// does not handle rgb by %
function fsConvertAnyRgbToHex(rgbStr)
{
    var colours =  rgbStr.match(/rgb\([\d,\s]*\)/gi);
    if(colours)
        for (var i=0;i<colours.length;i++)
        {
            colours[i] = colours[i].replace(/[rgb\(\)\s]/gi, "");
            var vals = colours[i].split(",");
            var r = parseInt(vals[0],10).toString(16).toUpperCase();
            var g = parseInt(vals[1],10).toString(16).toUpperCase();
            var b = parseInt(vals[2],10).toString(16).toUpperCase();
            r = r.length==1 ? "0"+r : r;
            g = g.length==1 ? "0"+g : g;
            b = b.length==1 ? "0"+b : b;
            rgbStr = rgbStr.replace(/rgb\([\d,\s]*\)/i ,"#"+r+g+b);
        }
    return rgbStr;
}


