<!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">

    //-------------------------------------------------------------------------
    // HTML5 Database
    //-------------------------------------------------------------------------
    var dbs = [];
    var quotas = [2000000, 2000000];
    var names = ['mydb', 'rand' + Math.random()];
    function openDb(index) {
        try {
            databaseOutput('Openning db with name: ' + names[index]);
            return openDatabase(names[index], "1.0", "Apache Cordova Demo", quotas[index]);
        } catch (e) {
            databaseOutput('Got exception: ' + e);
        }
    }

    var callDatabase = function(index) {
        var db = dbs[index] = openDb(index);
        if (!db) {
            return;
        }
        databaseOutput("Database opened.");
        db.transaction(function (tx) {
            tx.executeSql('DROP TABLE IF EXISTS DEMO');
            tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)', [],
                 function(tx,results) { console.log("Created table"); },
                 function(tx,err) { alert("Error creating table: "+err.message); });
            tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")', [],
                 function(tx,results) { console.log("Insert row1 success"); },
                 function(tx,err) { alert("Error adding 1st row: "+err.message); });
            tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")', [],
                 function(tx,results) { console.log("Insert row2 success"); },
                 function(tx,err) { alert("Error adding 2nd row: "+err.message); });
            databaseOutput("Data written to DEMO table.");
            console.log("Data written to DEMO table.");

            tx.executeSql('SELECT * FROM DEMO', [], function (tx, results) {
                var len = results.rows.length;
                var text = "DEMO table: " + len + " rows found.<br>";
                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
                for (var i=0; i<len; i++){
                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
                }
                text = text + "</table>";
                databaseOutput(text);
            }, function(tx, err) {
                alert("Error processing SELECT * SQL: "+err.message);
            });
            tx.executeSql('SELECT ID FROM DEMO', [], function (tx, results) {
                var len = results.rows.length;
                var text = "DEMO table: " + len + " rows found.<br>";
                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
                for (var i=0; i<len; i++){
                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + "</td></tr>";
                }
                text = text + "</table>";
                databaseOutput(text);
            }, function(tx, err) {
                alert("Error processing SELECT ID SQL: "+err.message);
            });
            
        },
        function(err) {
            console.log("Transaction failed: " + err.message);
        });


    };

    var readDatabase = function(index) {
        var db = dbs[index];
    	if (!db) {
            db = dbs[index] = openDb(index);
            if (!db) {
                return;
            }
        }
        db.transaction(function (tx) {
            tx.executeSql('SELECT * FROM DEMO WHERE id=2', [], function (tx, results) {
                var len = results.rows.length;
                var text = "DEMO table: " + len + " rows found.<br>";
                text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
                for (var i=0; i<len; i++){
                    text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
                }
                text = text + "</table>";
                databaseOutput(text);
            }, function(tx, err) {
                alert("Error processing SELECT * WHERE id=2 SQL: "+err.message);
            });
        });
    }

    function increaseQuota(index) {
        quotas[index] *= 2;
        databaseOutput('quota ' + index + ' is now ' + quotas[index]);
    }

    var databaseOutput = function(s) {
        var el = document.getElementById("database_results");
        el.innerHTML = el.innerHTML + s + "<br>";
        el.scrollByLines(20000);
    };
    
    /**
     * Function called when page has finished loading.
     */
    function init() {
        document.addEventListener("deviceready", function() {
            console.log("Device="+device.platform+" "+device.version);
        }, false);
    }

</script>

  </head>
  <body onload="init();" id="stage" class="theme">
  
    <h1>HTML5 Database</h1>   
    <div id="info">
        <b>Results:</b><br>
        <span id="database_results"></span>
    </div>
    <h2>Action</h2>
    <div class="btn large" onclick="callDatabase(0);">Create, Add, Read Database (Constant name)</div>
    <div class="btn large" onclick="readDatabase(0);">Read Database (Constant name)</div>
    <div class="btn large" onclick="increaseQuota(0);">Increase Quota (Constant name)</div>
    <div class="btn large" onclick="callDatabase(1);">Create, Add, Read Database (Random Name)</div>
    <div class="btn large" onclick="readDatabase(1);">Read Database (Random Name)</div>
    <div class="btn large" onclick="increaseQuota(1);">Increase Quota (Random Name)</div>
    <div class="btn large" onclick="location = location.href">Reload Page</div>
    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>    
  </body>
</html>      
