<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onReady()" viewSourceURL="srcview/index.html">
    
    <mx:Script>
        <![CDATA[
            [Bindable] private var bandwidthDay:Number;
            [Bindable] private var bandwidthLoad:Number;
            
            private function onReady():void
            {
                calcBandwidth();
            }
        
            private function calcBandwidth():void
            {
                
                var size:Number = stripChars(widgetSize.text);
                var load:Number = stripChars(widgetLoads.text);
                
                if(hasMoreData.selected) 
                    size += stripChars(additionalSize.text);
                
                if(isPolling.selected)
                    size += (Math.floor(stripChars(duration.text) / stripChars(frequency.text)) * stripChars(pollRequestSize.text));    
                
                bandwidthDay = (size/1024) * load / 1024;
                bandwidthLoad = (bandwidthDay / load) * 1048576;
            }
            
            private function calcCost(downBandwidth:Number):String
            {
                //S3 - US
                var storage:Number = Number(stripChars(widgetSize.text)/1024/1024) ;
                var uploadbandwidth:Number = 0;
                var downloadbandwidth:Number = downBandwidth;
                var plrequests:Number = 0;
                var allrequests:Number = Number(stripChars(widgetLoads.text)) ;
                  
                // pricing
                var storagerate:Number = 0.15 ;
                var uploadbandwidthrate:Number = 0.10 ;
                var plrequestrate:Number = 0.00001 ;
                var allrequestrate:Number = 0.000001 ;
                
                var nss:Number = round(calculateStorageUS(storage));
                var nsu:Number = round(uploadbandwidth  * uploadbandwidthrate) ;
                var nsd:Number = round(calculateDownloadBandwidth(downloadbandwidth));
                var nsr:Number = round(plrequests * plrequestrate) + round(allrequests * allrequestrate);
        
                trace("sto: "+nss);
                trace("up: "+nsu);
                trace("dl: "+nsd);
                trace("requests: "+nsr);
        
                return format(nss + nsu + nsd + nsr);
            }
            
            private function calculateStorageUS(size:Number):Number
            {
                var result:Number;
            
                var storagerate1:Number = 0.15 ; //first 50TB
                var storagerate2:Number = 0.14 ; //next 50TB
                var storagerate3:Number = 0.13 ; //next 400TB
                var storagerate4:Number = 0.12 ; //next all
                
        
                result = (50 * 1024 * storagerate1 ) + (50 * 1024 * storagerate2 ) + (400 * 1024 * storagerate3 ) + (size - 512000) * storagerate4 ;
                if(size<= 512000)
                    result = (50 * 1024 * storagerate1 ) + (50 * 1024 * storagerate2 ) + (size - 102400) * storagerate3 ;
                if(size<= 102400)
                    result = (50 * 1024 * storagerate1) + (size - 51200) * storagerate2 ;
                if(size<= 51200)
                    result = size  * storagerate1 ;
                    
                return result;
            }
            
            private function calculateDownloadBandwidth(downloadbandwidth:Number):Number
            {
                var result:Number;
                        
                var downloadbandwidthrate1:Number = 0.17 ; //first 10TB
                var downloadbandwidthrate2:Number = 0.13 ; //next 40TB
                var downloadbandwidthrate3:Number = 0.11 ; //next 100TB
                var downloadbandwidthrate4:Number = 0.10 ; //next all
        
                result = (10240 * downloadbandwidthrate1) + (40960 * downloadbandwidthrate2) + (100 * 1024 * downloadbandwidthrate3) + (downloadbandwidth - 153600) * downloadbandwidthrate4;
                if(downloadbandwidth <= 153600)
                    result = (10240 * downloadbandwidthrate1) + (40 * 1024 * downloadbandwidthrate2) + (downloadbandwidth - 51200) * downloadbandwidthrate3;
                if(downloadbandwidth <= 51200)
                    result = 10240 * downloadbandwidthrate1 + (downloadbandwidth - 10240) * downloadbandwidthrate2 ;
                if(downloadbandwidth <= 10240)
                    result = downloadbandwidth  * downloadbandwidthrate1 ;
                    
                return result;
            }
                        
            private function stripChars(value:String):Number
            {
                var myPattern:RegExp = /[^0-9]/gi;  
                value = value.replace(myPattern,"");
    
                return Number(value);
            }
            
            private function floor(number:Number):Number
            {
              return Math.floor(number*Math.pow(10,2))/Math.pow(10,2);
            }
            
            //roundup (financial rounding)
            private function round(number:Number):Number
            {
                return Math.ceil(number*1000)/1000;
            }
            
            //roundup (financial rounding)
            private function roundToNearest(number:Number):Number
            {
                if(number == 0) return 0;
                if(number <= 0.012) return 0.01;
                return Math.ceil(number*10000)/10000;
            }
            
            private function format(number:Number):String
            {
                return CommaFormatted(CurrencyFormatted(String(number)));
            }
            
            private function CurrencyFormatted(amount:String):String
            {
                var i:Number = parseFloat(amount);
                var minus:String = '';
                if(i < 0) { minus = '-'; }
                i = Math.abs(i);
                i = parseInt(String((i + .005) * 100));
                i = i / 100;
                var s:String = new String(i);
                if(s.indexOf('.') < 0) { s += '.00'; }
                if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
                s = minus + s;
                return s;
            }
            
            private function CommaFormatted(amount:String):String
            {
                var delimiter:String = ","; // replace comma if desired
                var a:Array = amount.split('.',2)
                var d:String = a[1];
                var i:Number = parseInt(a[0]);
                if(isNaN(i)) { return ''; }
                var minus:String = '';
                if(i < 0) { minus = '-'; }
                i = Math.abs(i);
                var n:String = new String(i);
                var ary:Array = [];
                while(n.length > 3)
                {
                    var nn:String = n.substr(n.length-3);
                    ary.unshift(nn);
                    n = n.substr(0,n.length-3);
                }
                if(n.length > 0) { ary.unshift(n); }
                n = ary.join(delimiter);
                if(d.length < 1) { amount = n; }
                else { amount = n + '.' + d; }
                amount = minus + amount;
                return amount;
            }
        ]]>
    </mx:Script>
    
    <mx:Panel layout="absolute" right="10" bottom="10" left="10" top="10" title="Bandwidth Calculator">
        <mx:Form x="0" y="0" width="100%" height="100%">
            <mx:FormItem label="Widget Size" toolTip="Size of widget in KiloBytes">
                <mx:HBox width="100%">
                    <mx:TextInput id="widgetSize" width="120" change="calcBandwidth()" text="55"/>
                    <mx:Label text="KBs"/>
                </mx:HBox>
            </mx:FormItem>
            <mx:FormItem label="Loads Per Day" toolTip="Number of times a widget is loaded per day">
                <mx:TextInput id="widgetLoads" width="120" change="calcBandwidth()" text="400,000"/>
            </mx:FormItem>
            <mx:FormItem label="Additional Data" toolTip="If your widget has additional data loaded">
                <mx:HBox>
                    <mx:CheckBox id="hasMoreData" width="100%" change="calcBandwidth()" selected="false"/>
                    <mx:HBox enabled="{hasMoreData.selected}">
                        <mx:TextInput id="additionalSize" width="98" change="calcBandwidth()" text="5"/>
                        <mx:Label text="KBs"/>
                    </mx:HBox>
                </mx:HBox>
            </mx:FormItem>
            <mx:FormItem label="Polling" toolTip="If you have requests that occur on an interval">
                    <mx:CheckBox id="isPolling" width="100%" change="calcBandwidth()" selected="false"/>
            </mx:FormItem>
            <mx:FormItem label="Poll Request Size" enabled="{isPolling.selected}" toolTip="Size of the entire poll request">
                <mx:HBox width="100%">
                    <mx:TextInput id="pollRequestSize" width="120" change="calcBandwidth()" text="5"/>
                    <mx:Label text="KBs"/>
                </mx:HBox>
            </mx:FormItem>
            <mx:FormItem label="Frequency" enabled="{isPolling.selected}" toolTip="How often does the widget poll?">
                <mx:HBox width="100%">
                    <mx:TextInput id="frequency" width="120" change="calcBandwidth()" text="10"/>
                    <mx:Label text="seconds"/>
                </mx:HBox>
            </mx:FormItem>
            <mx:FormItem label="Average Duration" enabled="{isPolling.selected}" toolTip="How long is the widget loaded and polling?">
                <mx:HBox width="100%">
                    <mx:TextInput id="duration" width="120" change="calcBandwidth()" text="60"/>
                    <mx:Label text="seconds"/>
                </mx:HBox>
            </mx:FormItem>
            <mx:FormItem label="Bandwidth Per Load">
                <mx:Label id="perLoad" text="{round(bandwidthLoad)} KBs" width="100%"/>
            </mx:FormItem>
            <mx:FormItem label="Bandwidth Per Day">
                <mx:Label id="perDay" text="{round(bandwidthDay)} GBs" width="100%"/>
            </mx:FormItem>
            <mx:FormItem id="perMonth" label="Bandwidth Per Month">
                <mx:Label text="{round(bandwidthDay * 30)} GBs" width="100%"/>
            </mx:FormItem>
            <mx:FormItem label="Cost Per Month" toolTip="Cost Per Month is calculated using current Amazon S3 (US) pricing" >
                <mx:Label text="${calcCost(bandwidthDay*30)}" width="100%"/>
            </mx:FormItem>
        </mx:Form>
    </mx:Panel>
    
</mx:Application>