Minggu, 28 Februari 2010

Flash Date Calculation Class

// ---------------------------------------
// The script in fla's frame:
//----------------------------------------
import plugs.data.DateHelper;

var tf:TextField = new TextField();
tf.multiline = tf.wordWrap = tf.background = true;
tf.autoSize = "left";
tf.width = 250;
addChild(tf);

var curDate:Date = new Date();
tf.appendText("\n" + curDate.toString());

var lastDate:Date = DateHelper.subtractDate(curDate, 0, 27, 3, 4);
tf.appendText("\n" + lastDate.toString());

var cur:Date = DateHelper.addDate(lastDate, 1, 3, 3, 4);
tf.appendText("\n" + cur.toString());

var difIna:String = DateHelper.difIndonesian(lastDate, curDate);
tf.appendText("\n" + difIna);

tf.appendText("\n" + DateHelper.difEnglish(lastDate, curDate));


-------------------------------------------------------
The result:
-------------------------------------------------------
Sun Feb 28 23:38:10 GMT+0700 2010
Sat Feb 27 20:35:06 GMT+0700 2010
Sun Feb 28 23:38:10 GMT+0700 2010
1 hari 3 jam 3 menit 4 detik
1 days 3 hours 3 minutes 4 seconds

-------------------------------------------------------
The helper class:
-------------------------------------------------------
/**
* Flash 10
* plugs framework
* DateHelper
* mi_kuncoro@yahoo.co.id
* www.icesflash.com
*//
package plugs.data
{
public class DateHelper
{
static protected const msS:Number = 1000;
static protected const msM:Number = 60000;
static protected const msH:Number = 3600000;
static protected const msD:Number = 86400000;

static public function addDate(dt:Date, d:Number, h:Number=0, m:Number=0, s:Number=0):Date
{
var v:Number = dt.valueOf() + d * msD + h * msH + m * msM + s * msS;
return new Date(v);
}

static public function subtractDate(dt:Date, d:Number, h:Number=0, m:Number=0, s:Number=0):Date
{
var v:Number = dt.valueOf() - d * msD - h * msH - m * msM - s * msS;
return new Date(v);
}

static public function difDate(dA:Date, dB:Date):Object
{
var n:Number = Math.abs(dA.valueOf() - dB.valueOf());
var ret:Object = new Object();
ret.day = Math.floor(n/msD);
var n0:Number = n % msD;
ret.hour = Math.floor(n0/msH);
var n1:Number = n0 % msH;
ret.minute = Math.floor(n1/msM);
var n2:Number = n1 % msM;
ret.second = n2 / msS;
return ret;
}

static public function difEnglish(dA:Date, dB:Date):String
{
var o:Object = difDate(dA, dB);
return o.day + " days "
+ o.hour.toString() + " hours "
+ o.minute.toString() + " minutes "
+ o.second.toString() + " seconds";
}

static public function difIndonesian(dA:Date, dB:Date):String
{
var o:Object = difDate(dA, dB);
return o.day + " hari "
+ o.hour.toString() + " jam "
+ o.minute.toString() + " menit "
+ o.second.toString() + " detik";
}

static public function difDay(dA:Date, dB:Date):Number
{
return (dA.valueOf() - dB.valueOf())/msD;
}

static public function difHour(dA:Date, dB:Date):Number
{
return (dA.valueOf() - dB.valueOf())/msH;
}

static public function difMinute(dA:Date, dB:Date):Number
{
return (dA.valueOf() - dB.valueOf())/msM;
}

static public function difSecond(dA:Date, dB:Date):Number
{
return (dA.valueOf() - dB.valueOf())/msS;
}
}
}

Senin, 22 Februari 2010

Flash Calculator with Math Parser

This is the first flash calculator I have developed for commercial purpose. If any cellular (handphone) company wants to use it for promotion, just email me at mi_kuncoro@yahoo.co.id

Jumat, 19 Februari 2010

MathParser class

package
{
public class MathParser
{
static public const RAD:int = 0;
static public const DEG:int = 1;
static public const GRAD:int = 2;

static protected const _pi:Number = Math.PI;

static public var instance:MathParser = new MathParser(1);


protected var _val :Number;
protected var _fac :Number;
protected var _mode :int;
protected var _rgxs :Array;
protected var functionList:Array =
["abs", "acos", "asin", "atan", "ceil", "cos", "exp", "floor", "log", "sin", "sqrt", "tan"];

public function MathParser( md:int )
{
mode  = md;
_rgxs = new Array(10);
_rgxs[0] = /[ \n\r\t]/g;
_rgxs[1] = /(?<=[\d\)])(?=[a-df-z\(])|(?<=pi)(?=[^\+\-\*\/\\^!)])|(?<=\))(?=\d)|(?<=[^\/\*\+\-])(?=exp)/i;
_rgxs[2] = /([a-z]*)\(([^\(\)]+)\)(\^|!?)/i;
_rgxs[3] = /([a-z]{2,})([\+-]?\d+,*\d*[eE][\+-]*\d+|[\+-]?\d+,*\d*)/i;
_rgxs[4] = /\{(.+)\}!" )/;
_rgxs[5] = /([\d.]+,*[\d.]*[eE][\+-]?[\d.]+|[\d.]+,*[\d.]*)!/;
_rgxs[6] = /\{(.+)\}\^(-?[\d.]+,*[\d.]*[eE][\+-]?[\d.]+|-?[\d.]+,*[\d.]*)/;
_rgxs[7] = /([\d.]+,*[\d.]*e[\+-]?[\d.]+|[\d.]+,*[\d.]*)\^(-?[\d.]+,*[\d.]*[eE][\+-]?[\d.]+|-?[\d.]+,*[\d.]*)/;
_rgxs[8] = /([\+-]?[\d.]+,*[\d.]*[eE][\+-]?[\d.]+|[\-\+]?[\d.]+,*[\d.]*)([\/\*])(-?[\d.]+,*[\d.]*[eE][\+-]?[\d.]+|-?[\d.]+,*[\d.]*)/;
_rgxs[9] = /([\+-]?[\d.]+,*[\d.]*[eE][\+-]?[\d.]+|[\+-]?[\d.]+,*[\d.]*)([\+-])(-?[\d.]+,*[\d.]*[eE][\+-]?[\d.]+|-?[\d.]+,*)[\d.]*/;
}

// Getter & Setter
public function get Result():Number { return _val; }

public function get mode():int { return _mode; }
public function set mode(n:int):void
{
_mode = n;
switch( n )
{
case RAD : _fac = 1.0; break;
case DEG : _fac = 2.0 * _pi / 360.0; break;
case GRAD: _fac = 2.0 * _pi / 400.0; break;
}
}

public function parseFormula( str:String ):Number
{
try
{
var ss = str.replace(/[  \n\r\t]/g, " ");
//replace all constants

ss = ss.replace(/PI/g, Math.PI.toString());
ss = ss.replace(/E/g, Math.E.toString());
ss = ss.replace(/LN2/g, Math.LN2.toString());
ss = ss.replace(/LN10/g, Math.LN10.toString());
ss = ss.replace(/LOG2E/g, Math.LOG2E.toString());
ss = ss.replace(/LOG10E/g, Math.LOG10E.toString());
ss = ss.replace(/SQRT1_2/g, Math.SQRT1_2.toString());
ss = ss.replace(/SQRT2/g, Math.SQRT2.toString());

//remove blank spaces
ss = ss.replace( _rgxs[0], "" );

// remove others

ss = ss.replace(_rgxs[1],"*");
ss = ss.replace("pi", Math.PI.toString());

var o:Object = _rgxs[2].exec( ss );

while( o != null )
{
if( o[3].length > 0 )
{
ss = ss.replace( o[0], "{" + o[1] + evalString( o[2] ) + "}" + o[3] );
}
else
{
ss = ss.replace( o[0], o[1] + evalString( o[2] ) );
}
o = _rgxs[2].exec( ss );
}

_val = Number( evalString( ss ) );

return _val;
}
catch (e:Error)
{
trace(e);
return NaN;
}
return NaN;
}

protected function evalString( ss:String ):String
{
//trace(ss);
var oo:Object = _rgxs[3].exec( ss );

while( oo != null && functionList.indexOf(oo[1].toLowerCase() ) > -1  )
{
switch( oo[1].toLowerCase() )
{
case "abs" : ss = ss.replace( oo[0], Math.abs( Number( oo[2] ) ).toString() ); break;
case "acos" : ss = ss.replace( oo[0], Math.acos( _fac * Number( oo[2] ) ).toString() ); break;
case "asin" : ss = ss.replace( oo[0], Math.asin( _fac * Number( oo[2] ) ).toString() ); break;
case "atan" : ss = ss.replace( oo[0], Math.atan( _fac * Number( oo[2] ) ).toString() ); break;
case "cos" : ss = ss.replace( oo[0], Math.cos( _fac * Number( oo[2] ) ).toString() ); break;
case "ceil" : ss = ss.replace( oo[0], Math.ceil( Number( oo[2] ) ).toString() ); break;
case "exp" : ss = ss.replace( oo[0], Math.exp( Number( oo[2] ) ).toString() ); break;
case "floor": ss = ss.replace( oo[0], Math.floor( Number( oo[2] ) ).toString() ); break;
case "log" : ss = ss.replace( oo[0], Math.log( Number( oo[2] ) ).toString() ); break;
case "sin" : ss = ss.replace( oo[0], Math.sin( _fac * Number( oo[2] ) ).toString() ); break;
case "sqrt" : ss = ss.replace( oo[0], Math.sqrt( Number( oo[2] ) ).toString() ); break;
case "tan" : ss = ss.replace( oo[0], Math.tan( _fac * Number( oo[2] ) ).toString() ); break;
}
oo = _rgxs[3].exec( ss );
}

// {5}!
var n:Number;
oo = _rgxs[4].exec( ss );
while( oo != null )
{
n = Number( oo[1] );
if( (n < 0) && (n != Math.round(n)) ){trace("ERROR........");}
ss = ss.replace( _rgxs[4], checkNumber( Number( oo[1] ) ).toString() );
oo = _rgxs[4].exec( ss );
}

// 5!
oo = _rgxs[5].exec( ss );
while( oo != null )
{
n = Number( oo[1] );
if( (n < 0) && (n != Math.round(n)) ){trace("ERROR........");}
ss = ss.replace( _rgxs[5], checkNumber( Number( oo[1] ) ).toString() );
oo = _rgxs[5].exec( ss );
}

// {-2}^-1
oo = _rgxs[6].exec( ss );

while( oo != null )
{
ss = ss.replace( oo[0], Math.pow( Number( oo[1] ), Number( oo[2] ) ).toString() );
oo = _rgxs[6].exec( ss );
}

// 2^-1
oo = _rgxs[7].exec( ss );
while( oo != null )
{
ss = ss.replace( _rgxs[7], Math.pow( Number( oo[1] ), Number( oo[2] ) ).toString() );
oo = _rgxs[7].exec( ss );
}

oo = _rgxs[8].exec( ss );

var ret:Number;
while( oo != null )
{
if (oo[2] == "*")
{
ret = Number( oo[1] ) * Number( oo[3] );
if( (ret < 0) || (oo.index == 0) ) ss = ss.replace( _rgxs[8], ret.toString() );
else ss = ss.replace( oo[0], "+" + ret );
}
else if (oo[2] == "/")
{
ret = Number( oo[1] ) / Number( oo[3] );
if( (ret < 0) || (oo.index == 0) ) ss = ss.replace( _rgxs[8], ret.toString() );
else ss = ss.replace( _rgxs[8], "+" + ret );
}
oo = _rgxs[8].exec( ss );
}

oo = _rgxs[9].exec( ss );
while( oo != null )
{
if (oo[2] == "+")
{
ret = Number( oo[1] ) + Number( oo[3] );
if( (ret < 0) || (oo.index == 0) ) ss = ss.replace( _rgxs[9], ret.toString() );
else ss = ss.replace( _rgxs[9], "+" + ret );
}
else if (oo[2] == "-")
{
ret = Number( oo[1] ) - Number( oo[3] );
if( (ret < 0) || (oo.index == 0) ) ss = ss.replace( _rgxs[9], ret.toString() );
else ss = ss.replace( _rgxs[9], "+" + ret );
}
oo = _rgxs[9].exec( ss );
}

if( ss.substr(0,2) == "--" ) ss = ss.substr(2);

return ss;
}

protected function checkNumber( n:Number ):Number
{
return (n == 0.0) ? 1.0 : (n * checkNumber( n - 1.0 ));
}
}
}

TestMathParser Class

package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.ui.Keyboard;
import flash.utils.getTimer;

import MathParser;
import MathFormula;

public class TestMathParser extends Sprite
{
var mParser :MathParser  = new MathParser(0);
var mFormula :MathFormula = new MathFormula();
var tfLabel1 :TextField = new TextField();
var tfLabel2 :TextField = new TextField();
var tfLabel3 :TextField = new TextField();
var tfExpression:TextField = new TextField();
var tfFormula :TextField = new TextField();
var tfParam :TextField = new TextField();
var tfResult1 :TextField = new TextField();
var tfResult2 :TextField = new TextField();
var tfMessage :TextField = new TextField();
var tfCont :Sprite = new Sprite();
var aTransforms :Array = [ new ColorTransform(1.4, 1.0, 1.5), new ColorTransform(0.6, 0.6, 0.8), new ColorTransform()];

public function TestMathParser()
{
tfLabel1.mouseEnabled = tfLabel2.mouseEnabled = tfLabel3.mouseEnabled = false;

tfExpression.type = tfFormula.type = tfParam.type = "input";
tfExpression.wordWrap = tfFormula.wordWrap = tfParam.wordWrap = true;
tfExpression.width = tfFormula.width = tfParam.width = 320;
tfExpression.height = tfFormula.height = tfParam.height = 50;
tfResult1.width = tfResult2.width = 320;
tfResult1.height = tfResult2.height = 20;

tfResult1.border = tfResult2.border = true;
tfExpression.background = tfFormula.background = tfParam.background = true;
tfResult1.background = tfResult2.background = true;
tfExpression.backgroundColor = tfFormula.backgroundColor =0xEFDEFF;
tfParam.backgroundColor = 0xECCECC;
tfResult1.backgroundColor = tfResult2.backgroundColor = 0x000000;
tfResult1.borderColor = tfResult2.borderColor = 0x555555;
tfResult1.textColor = tfResult2.textColor = tfMessage.textColor = 0xFFFFFF;
tfLabel1.textColor = tfLabel2.textColor = tfLabel3.textColor = 0xCCCCCC;

tfLabel1.x = tfLabel2.x = tfLabel3.x = 15;
tfExpression.x = tfFormula.x = tfParam.x = 15;
tfResult1.x = tfResult2.x = 15;

tfLabel1.y = 5;
tfExpression.y = 25;
tfResult1.y = 77;

tfLabel2.y = 102;
tfFormula.y = 124;
tfLabel3.y = 176;
tfParam.y = 196;
tfResult2.y = 248;

tfCont.x = 15;
tfCont.y = 275;

tfMessage.x = 10;
tfMessage.y = 2;
tfMessage.autoSize = "left";
tfMessage.mouseEnabled = tfMessage.selectable = false;

var tff1:TextFormat = new TextFormat("Verdana", 12, 0xFFFFFF, true);
var tff2:TextFormat = new TextFormat("Verdana", 11, 0x000000, true);
tfLabel1.defaultTextFormat = tfLabel2.defaultTextFormat = tfLabel3.defaultTextFormat = tff1;
tfResult1.defaultTextFormat = tfResult2.defaultTextFormat = tfMessage.defaultTextFormat = tff1;
tfLabel1.autoSize = tfLabel2.autoSize = tfLabel3.autoSize = "left";
tfExpression.defaultTextFormat = tfFormula.defaultTextFormat = tfParam.defaultTextFormat = tff2;

tfLabel1.text = "Expression:";
tfLabel2.text = "Formula   :";
tfLabel3.text = "Parameters:";
tfExpression.text = "6*3+2*(-2-6)";
tfFormula.text = "2*x+3*y^2+log(5)+sin(10)";
tfParam.text = "x=2, y=4";
tfMessage.text = "Enter or click here to calculate";

addChild(tfLabel1);
addChild(tfLabel2);
addChild(tfLabel3);
addChild(tfExpression);
addChild(tfFormula);
addChild(tfParam);
addChild(tfResult1);
addChild(tfResult2);
addChild(tfCont);
tfCont.addChild(tfMessage);

btnUp(null);

graphics.lineStyle(5, 0xC9C5C9, 0.7);
graphics.beginFill(0x252525);
graphics.drawRoundRect(0,0,350,320,5,5);
graphics.endFill();
graphics.lineStyle(1, 0xDEDEDF, 1);
graphics.drawRoundRect(2,2,345,315,5,5);

var matrix = new Matrix();
matrix.createGradientBox(320,24,Math.PI/2);
tfCont.graphics.lineStyle(1, 0x555555, 0.7);
tfCont.graphics.beginGradientFill("linear",
 [0x9A9A9A, 0x2A272A, 0x9A999B],
 [1,1,1],
 [0x25, 0xA9, 0xFF],
 matrix);
tfCont.graphics.drawRoundRect(0,0,320,24,5,5);
tfCont.graphics.endFill();
tfCont.mouseEnabled = true;

tfCont.addEventListener(MouseEvent.MOUSE_OVER, btnOver);
tfCont.addEventListener(MouseEvent.MOUSE_DOWN, btnDown);
tfCont.addEventListener(MouseEvent.MOUSE_OUT, btnOut);
tfCont.addEventListener(MouseEvent.MOUSE_UP, btnUp);
stage.addEventListener(KeyboardEvent.KEY_UP, kbUp);
}

function btnOver(e:MouseEvent) :void { tfCont.transform.colorTransform = aTransforms[0]; }
function btnDown(e:MouseEvent) :void { tfCont.transform.colorTransform = aTransforms[1]; }
function btnOut(e:MouseEvent) :void { tfCont.transform.colorTransform = aTransforms[2]; }
function btnUp(e:MouseEvent) :void
{
tfCont.transform.colorTransform = aTransforms[0];
calcExpression();
mFormula.formula = tfFormula.text;
mFormula.setParameters(tfParam.text);
tfResult2.text = mFormula.result.toString();
}

function kbUp(e:KeyboardEvent):void
{
if (e.keyCode != Keyboard.ENTER) return;

if (e.target == tfExpression)
{
calcExpression();
}
else if (e.target == tfFormula)
{
mFormula.formula = tfFormula.text;
tfResult2.text = mFormula.result.toString();
}
else if (e.target == tfParam.text)
{
mFormula.setParameters(tfParam.text);
tfResult2.text = mFormula.result.toString();
}
}

function calcExpression():void
{
var n:Number = mParser.parseFormula(tfExpression.text);
if (isNaN(n))
{
tfResult1.text = "ERROR";
}
else
{
tfResult1.text = n.toString();
}
}
}
}

MathFormula class

package
{
import MathParser;

public class MathFormula
{
protected var _f:String="";
protected var _p:Object;
protected var _v:Number;
protected var _e:String;

public function MathFormula()
{}

public function get formula():String { return _f; }
public function set formula(s:String):void
{
_f = s.replace(/[ \r\n\t]/g,"");
if (_p != null) evalMe();
}

public function get parameters():Object { return _p; }
public function set parameters(o:Object):void
{
_p = o;
if (_f != "") evalMe();
}

public function setParameters(s:String):Number
{
var ss:String = s.replace(/[ \r\n\t]/g,"");
_p = new Object();
_p.names = [];
_p.values = [];
var ar:Array = s.split(",");
var ai:Array;
var i:int = -1;
while(++i < ar.length)
{
ai=ar[i].split("=");
_p.names.push(ai[0].replace(/ /g, ""));
_p.values.push(Number(ai[1]));
}

if (_f != "") evalMe();
return _v;
}

public function get errorMessage():String { return _e; }

public function get result():Number { return _v; }

protected function evalMe():void
{
var rx:RegExp;
var s:String = "" + _f;
var i:int = -1;
while(++i < _p.names.length)
{
rx = new RegExp(_p.names[i], "g");
s = s.replace(rx,_p.values[i].toString());
}
_v = MathParser.instance.parseFormula(s);
}
}
}

Step to Flash Internet SpreadSheet

MathParser Created http://www.icesflash.com/MathParserTest.swf
ChartComponent nearly dinished http://www.icesflash.com/Chart.swf
... a litle bit more.....
WHo wants to joint?