<!DOCTYPE html>
<!--

 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.

-->
<html>
  <head>
    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
    <title>Cordova Mobile Spec</title>
    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
    <script type="text/javascript" charset="utf-8" src="uubench.js"></script>
<script>
    var exec = cordova.require('cordova/exec');
    var temp, pers, LICENSE_CONTENTS;
    function $(id) { return document.getElementById(id); }

    function copy_license(filesystem, callback) {
        filesystem.root.getFile("LICENSE", {create: true, exclusive: false}, function(entry) {
            entry.createWriter(function(writer) {
                writer.onwriteend = function(evt) {
                    callback();
                };
                writer.write(LICENSE_CONTENTS);
            }, function(err) {
                alert('Error creating LICENSE FileWriter');
            });
        }, function(err) {
            alert('Error copying LICENSE to a file system');
        });
    }

    var suite = new uubench.Suite({
        start:function() {
            $('loading').innerHTML = "BENCHMARKING IN PROGRESS...";
        },
        result: function(name, stats) {
            var secs = stats.elapsed/1000;
            var itspersec = stats.iterations / secs;
            $('table-results').innerHTML += '<tr><td>' + name + '</td><td>' + itspersec + ' per second.</td></tr>';
            console.log(name + ' bench complete.');
            results[name] = stats;
        },
        min: 2000, // each benchmark should run for at least 2000ms
        done:function() { 
            $('loading').innerHTML = "Benchmarks complete.";
            $('backBtn').style.display="block";
        }
    });
    var results = {};

    document.addEventListener("deviceready", function() {
        deviceReady = true;
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "../LICENSE", true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (xhr.responseText.length > 0) {
                    LICENSE_CONTENTS = xhr.responseText;
                } else {
                    alert('Some prereq XHR stuff to get license content failed mang.');
                }
                window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(p_fs) {
                    pers = p_fs;
                    copy_license(pers, function() {
                        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function(t_fs) {
                            temp = t_fs;
                            copy_license(temp, function() {
                                setTimeout(bench, 250);
                            });
                        }, function(t_e) {
                            alert('Failed to get TEMPORARY File System');
                        });
                    });
                }, function(p_e) {
                    alert('Failed to get PERSISTENT File System');
                });
            }
        };
        xhr.send(null);
    });

    window.onload = function() {
        window.setTimeout(function() {
            if (!deviceReady) {
                alert("Error: Cordova did not initialize.  Demo will not run correctly.");
            }
        }, 1000);
    };
function bench() {
    suite.bench("Echo exec callbacks", function(next) {
        exec(function() {
            // win
            next();
        }, function() {
            // fail
            next();
        }, "Echo", "echo", ["test"]);
    });
    suite.bench("Echo exec invocations", function(next) {
        exec(function() {
            // win
        }, function() {
            // fail
        }, "Echo", "echo", ["test"]);
        next();
    });
    suite.bench("XHR to within-package 11kb asset.", function(next) {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "../LICENSE", true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                // The result status is being compared to 0 for success instead of 200. This is because the file and ftp schemes do not use HTTP result codes.
                if (xhr.status == 0 && xhr.responseText.length > 0) {
                    next();
                } else {
                    alert('There was a problem during XHR file read!');
                }
            }
        };
        xhr.send(null);
    });
    if (temp) {
        suite.bench("Get contents of 11kb asset located on TEMPORARY File System using FileReader's readAsText method.", function(next) {
            temp.root.getFile("LICENSE", null, function(entry) {
                entry.file(function(file) {
                    var reader = new FileReader();
                    reader.onloadend = function(evt) {
                        next();
                    };
                    reader.readAsText(file);
                }, function(err) {
                    alert('Error getting File object from LICENSE file in TEMP FS.');
                });
            }, function(err) {
                alert('Error getting LICENSE file from root of TEMP FS.');
            });
        });
    }
    if (pers) {
        suite.bench("Get contents of 11kb asset located on PERSISTENT File System using FileReader's readAsText method.", function(next) {
            pers.root.getFile("LICENSE", null, function(entry) {
                entry.file(function(file) {
                    var reader = new FileReader();
                    reader.onloadend = function(evt) {
                        next();
                    };
                    reader.readAsText(file);
                }, function(err) {
                    alert('Error getting File object from LICENSE file in PERSISTENT FS.');
                });
            }, function(err) {
                alert('Error getting LICENSE file from root of PERSISTENT FS.');
            });
        });
    }
    suite.run();
}
</script>

  </head>
  <body id="stage" class="theme">
    <h1>Auto-Benchmarks</h1>
    <h2 id="loading"></h2>
    <table>
        <thead style="font-weight:bold;text-align:center;">
            <tr>
                <td>Name</td>
                <td>Results</td>
            </tr>
        </thead>
        <tbody id="table-results">
        </tbody>
    </table>
    <h2>&nbsp</h2><a href="javascript:" class="backBtn" style="display:none" id='backBtn' onclick="backHome();">Back</a><br>
  </body>
</html>      
