Resources/js/d/dascyllus.js
changeset 0 80c32ef237c6
child 1 b3419d05eabb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/js/d/dascyllus.js	Mon Sep 02 02:22:21 2013 -0700
@@ -0,0 +1,256 @@
+
+/*######################################################################
+### D A S C Y L L U S   N A M E S P A C E
+######################################################################*/
+var D = {
+
+	// Versions
+	platform:     Ti.getPlatform(),
+	name:         Ti.API.Application.getName(),
+	version:      Ti.API.Application.getVersion(),
+	ti_version:   Ti.getVersion(),
+	architecture: Ti.Platform.getArchitecture(),
+
+	// Declared windows, for easy referencing
+	window: {},
+
+	// Very first run of Dasycllus?
+	firstrun: false,
+
+	// Persistent storage DB handle.
+	db: null,
+
+	// The current TF server we'll be connected to;
+	//     uri: http://localhost:8080/
+	//     version: Thingfish 0.5.0 (build ...)
+	//
+	tf: null,
+
+
+	// Open a handle to the local database, initializing it
+	// if necessary and performing rudamentary upwards migrations.
+	//
+	initDB: function() {
+		this.db = Ti.Database.openFile(
+			Ti.Filesystem.getFile(
+				Ti.Filesystem.getApplicationDataDirectory(), 'dascyllus.db'
+			)
+		);
+
+		var rv = this.db.execute( 'PRAGMA user_version' );
+		var schema_version = parseInt( rv.fieldByName('user_version') );
+
+		var schemas_dir = Ti.Filesystem.getFile(
+				Ti.Filesystem.getApplicationDirectory(), 'sql' );
+		var current_version = schemas_dir.getDirectoryListing().length;
+
+		if ( schema_version == 0 ) {
+			this.notify( 'Welcome!', 'Dascyllus defaults installed.' );
+			this.firstrun = true;
+		}
+
+		if ( schema_version != current_version ) {
+			console.log( 'Dascyllus DB at version ' + schema_version +
+					', needs to be upgraded to ' + current_version + '.' );
+
+			while ( schema_version != current_version ) {
+				var update_version = schema_version + 1;
+				console.log( '  updating to version ' + update_version );
+
+				var line;
+				var schema_file = Ti.Filesystem.getFileStream(
+						Ti.Filesystem.getApplicationDirectory(), 'sql', update_version + '.sql' );
+				schema_file.open();
+
+				this.db.execute( 'BEGIN' );
+				while ( line = schema_file.readLine() ) this.db.execute( line.toString() );
+
+				this.db.execute( 'PRAGMA user_version = ' + update_version  );
+				this.db.execute( 'COMMIT' );
+
+				schema_version = update_version;
+				schema_file.close();
+			}
+		}
+
+		return this.db;
+	},
+
+
+	// Return a preference's current value, or null if nonexistent.
+	//
+	getPref: function( pref ) {
+		var row = this.db.execute( "SELECT val FROM prefs WHERE key=?", pref );
+		if ( ! row.isValidRow() ) return null;
+
+		var value = row.fieldByName( 'val' );
+		row.close();
+
+		return value;
+	},
+
+
+	// Return a preference's current value as a boolean.
+	//
+	getBoolPref: function( pref ) {
+		return this.getPref( pref ) == '1'
+	},
+
+
+	// Insert or update a preference value.
+	//
+	setPref: function( pref, value ) {
+		this.db.execute( 'BEGIN' );
+
+		// Row already exists, remove it first.
+		if ( this.getPref( pref ) != null )
+			this.db.execute( 'DELETE FROM prefs WHERE key=?', pref );
+
+		this.db.execute( 'INSERT INTO prefs VALUES ( ?, ? )', pref, value );
+		this.db.execute( 'COMMIT' );
+	},
+
+
+	// Set a bool preference value.
+	//
+	setBoolPref: function( pref, value ) {
+		this.setPref( pref, (value ? '1' : '0') );
+	},
+
+
+	// Generic delayed callback that returns the timer handle.
+	//
+	delay: (function() {
+		var timer = null;
+		return function( callback, ms, clear_previous ) {
+			if ( clear_previous) clearTimeout( timer );
+			timer = setTimeout( callback, ms );
+			return timer;
+		};
+	})(),
+
+
+	// Create and show a new notification.
+	//
+	notify: function( title, message, callback ) {
+		if ( ! callback ) callback = function(){};
+
+		var notification = Ti.Notification.createNotification({
+			'title' : title,
+			'message' : message,
+			'timeout' : 10,
+			'callback' : callback,
+		});
+
+		notification.show();
+		return notification;
+	},
+
+
+	// Attempt a connection to a remote Thingfish server, and
+	// populate the D.tf variable.
+	//
+	checkServer: function( uri ) {
+		this.tf = null;
+
+		var serverOk = function( data, status, xhr ) {
+			var info = xhr.getResponseHeader( 'x-thingfish' );
+			if ( info ) {
+				D.tf = {
+					uri: uri,
+					version: data.version
+				};
+				D.notify( 'Connected.', info );
+			}
+			else {
+				D.notify( 'Unable to connect.', 'Not a Thingfish server?' );
+			}
+		};
+
+		$.ajax({
+			url:      uri,
+			sync:     false,
+			success:  serverOk,
+			error:    function( xhr, status, err ) {
+				D.notify( 'Unable to connect.', err );
+			},
+			dataType: 'json'
+		});
+	},
+
+
+	// Build the main menu.
+	//
+	setupMenu: function() {
+		var menu  = Ti.UI.createMenu();
+		var yep   = Ti.UI.createMenuItem( 'Yep' );
+
+		yep.addItem( 'About', function() {
+			if ( D.window.about && D.window.about.isVisible() ) {
+				D.window.about.focus();
+			}
+			else {
+				D.window.about = D.window.main.createWindow( 'app://window/about.html' );
+				D.window.about.setTopMost( true );
+				D.window.about.open();
+			}
+		});
+
+		yep.addItem( 'Preferences', function() {
+			if ( D.window.prefs && D.window.prefs.isVisible() ) {
+				D.window.prefs.focus();
+			}
+			else {
+				D.window.prefs = D.window.main.createWindow( 'app://window/prefs.html' );
+				D.window.prefs.open();
+			}
+		});
+
+		yep.addItem( 'Toggle Full Screen', function() {
+			D.window.main.setFullscreen( ! D.window.main.isFullscreen() );
+		});
+
+		menu.appendItem( yep );
+		Ti.UI.setMenu( menu );
+	},
+
+
+	/*######################################################################
+	### M O D E L S
+	######################################################################*/
+
+	// A Thingfish asset.
+	//
+	initModel: function() {
+		D.Asset = can.Model({
+			id     : 'oid',
+			findAll: 'GET '    + D.tf.uri + '/',
+			findOne: 'GET '    + D.tf.uri + '/{oid}',
+			create : 'POST '   + D.tf.uri + '/',
+			update : 'PUT '    + D.tf.uri + '/{oid}',
+			destroy: 'DELETE ' + D.tf.uri + '/{oid}',
+
+			// TODO: other metadata hooks?  diff model?
+			metadata: 'GET ' + D.tf.uri + '/{oid}/metadata',
+
+		}, {}).
+			bind( 'created', function( ev, asset ) {
+				console.debug( "Created a new asset " + asset.id );
+			}).
+			bind( 'updated', function( ev, asset ) {
+				console.debug( "Updated asset " + asset.id );
+			}).
+			bind( 'destroyed', function( ev, asset ) {
+				console.debug( "Removed asset " + asset.id );
+			}
+		);
+	},
+};
+
+
+// Initialization.
+//
+D.window.main = Ti.UI.getMainWindow();
+D.setupMenu();
+D.initDB();
+