var LocalDB = {
    db: '',
    enable: false,

    init: function() {
        try {
            if (!window.openDatabase) {
//                alert('not supported');
            } else {
                var shortName = 'API cache';
                var version = '1.0';
                var displayName = 'API data is cached';
                var maxSize = 1024 * 1024; // 1MB
                this.db = openDatabase(shortName, version, displayName, maxSize);

                // You should have a database instance in myDB.
                this.createTables();
                this.enable = true;

            }
        } catch(e) {
            // Error handling code goes here.
            if (e == INVALID_STATE_ERR) {
                // Version number mismatch.
                alert("Invalid database version.");
            } else {
                alert("Unknown error "+e+".");
            }
            return;
        }
    },

    /**
     * select$B$7$?7k2L$rJV$9(B
     * return Array
     */
    find: function(table, options) {
        // $B%G%U%)%k%HCM$N@_Dj(B
        options.select = options.select || ['*'];
        options.conditions = options.conditions || [];
        options.callback = options.callback || Function();
        var params = [];
        var results = [];

        // DB$B$,;H$($J$$%V%i%&%6$N>l9g(B
        if (!LocalDB.enable) {
            options.callback(results);
            return;
        }

        var sql = 'select ' + options.select.join(',') + ' from ' + table;
        if (0 < options.conditions.length) {
            sql += ' where ' + options.conditions[0];
            params = options.conditions[1];
        }
        sql += ';';

        this.db.transaction(
            function(transaction) {
                transaction.executeSql(sql, params, function(transaction, resultsObj) {
                    for (var i=0; i<resultsObj.rows.length; i++) {
                        results.push(resultsObj.rows.item(i));
                    }
                    options.callback(results);
                }, LocalDB.errorHandler);
            }
        );
    },

    /**
     * $B%G!<%?$r(Binsert$B$^$?$O(Bupdate$B$9$k(B
     */
    save: function(table, record, options) {
        if (!LocalDB.enable) return false;

        var sql = '';
        // $B%G!<%?$,B8:_$9$k>l9g$O!"(Bupdate
//        if (0 < this.find(table, options).length) {
//            sql = 'update ' + table + ' set ';
//            var set_sql = [];
//            var params = [];
//            $.each(record, function(i, v) {
//                set_sql.push(i + '=' + '?');
//                params.push(v);
//            });
//            sql += set_sql.join(',');
//            if (0 < options.conditions.length()) {
//                sql += ' where ' + options.conditions[0];
//                params.concat(options.conditions[1]);
//            }
//        // $B%G!<%?$,B8:_$7$J$$>l9g$O!"(Binsert
//        } else {
//            sql = 'insert into ' + table;
//
//            var set_sql = [];
//            var place_holder = [];
//            var params = [];
//            $.each(record, function(i, v) {
//                set_sql.push(i);
//                place_holder.push('?');
//                params.push(v);
//            });
//            sql += '(' + set_sql.join(',') + ')';
//            sql += ' values (' + place_holder.join(',') + ')';
//        }
        sql = 'insert or replace into ' + table;

        var set_sql = [];
        var place_holder = [];
        var params = [];
        $.each(record, function(i, v) {
            set_sql.push(i);
            place_holder.push('?');
            params.push(v);
        });
        sql += '(' + set_sql.join(',') + ')';
        sql += ' values (' + place_holder.join(',') + ')';
        sql += ';';
        this.db.transaction(function(transaction) {
            transaction.executeSql(sql, params, LocalDB.nullDataHandler, LocalDB.errorHandler);
        });
    },

    remove: function(table, options) {
        // $B%G%U%)%k%HCM$N@_Dj(B
        options.conditions = options.conditions || [];
        options.callback = options.callback || Function();
        var params = [];
        var results = [];

        // DB$B$,;H$($J$$%V%i%&%6$N>l9g(B
        if (!LocalDB.enable) {
            options.callback(results);
            return;
        }

        var sql = 'delete from ' + table;
        if (0 < options.conditions.length) {
            sql += ' where ' + options.conditions[0];
            params = options.conditions[1];
        }
        sql += ';';

        this.db.transaction(
            function(transaction) {
                transaction.executeSql(sql, params, function(transaction, resultsObj) {
//                    for (var i=0; i<resultsObj.rows.length; i++) {
//                        results.push(resultsObj.rows.item(i));
//                    }
                    options.callback(resultsObj);
                }, LocalDB.errorHandler);
            }
        );
    },

    /*! This creates the database tables. */
    createTables:function() {

        /* To wipe out the table (if you are still experimenting with schemas,
           for example), enable this block. */
        if (false) {
//        if (true) {
            this.db.transaction(
                function (transaction) {
                    transaction.executeSql('DROP TABLE items;');
                }
            );
        }

        this.db.transaction(
            function(transaction) {
                transaction.executeSql("CREATE TABLE IF NOT EXISTS items(hash TEXT NOT NULL PRIMARY KEY, url TEXT NOT NULL, body TEXT NOT NULL, updated DATE NOT NULL);", [], LocalDB.nullDataHandler, LocalDB.killTransaction);
            }
        );


    },

    /*! When passed as the error handler, this silently causes a transaction to fail. */
    killTransaction:function(transaction, error) {
        return true; // fatal transaction error
    },

    /*! When passed as the error handler, this causes a transaction to fail with a warning message. */
    errorHandler:function(transaction, error) {
        // Error is a human-readable string.
        alert('Oops.  Error was '+error.message+' (Code '+error.code+')');


        // Handle errors here
        var we_think_this_error_is_fatal = true;
        if (we_think_this_error_is_fatal) return true;
        return false;
    },

    /*! This is used as a data handler for a request that should return no data. */
    nullDataHandler:function(transaction, results) {
       // console.log(results);
       // console.log('null !');
    }
}
