﻿opus.server = {
	baseUrl: "",
	/**
	 * The core way to access the backend system.
	 *
	 * @param method is the HTTP method (GET|POST|PUT|DELETE)
	 * @param url is the sub url to hit (after the base url)
	 * @param payload is what to send up for POST requests
	 * @param options is how you pass in various callbacks
	 * 		options['onSuccess'] = the main success callback
	 * 		options['onFailure'] = call for general failures
	 */
	request: function(method, url, payload, options) {
		var args = {
			url: this.baseUrl + url
		};
		
		if (method == "GET") {
			args.preventCache = true;
		}
		
		var retvalue;
		if (options) {
			if (options.onSuccess) {
				args.load = options.onSuccess;
			}
			if (options.onFailure) {
				args.failOk = true;
				args.error = options.onFailure;
			}
		} else {
			args.sync = true;
			args.load = function(d) {
				retvalue = d;
			}
		}
		
		if (payload) {
			args.rawBody = payload;
		}
		
		var deferred = dojo.xhr(method, args, payload != null);
		if (args.sync) {
			return retvalue;
		}
	},
	fetchMessages: function(onSuccess, onFailure) {
		this.request('POST', '/messages/', null, {
			onSuccess: onSuccess,
			onFailure: onFailure
		});
	},
	list: function(inPath, inType, inExt, inCallback) {
		inPath = inPath || "";
		var result = this.request("GET", "/file/list/" + inPath), r;
		try {
			r = dojo.fromJson(result) || [];
		} catch (e) {
			r = [];
		}

		var urls;
		if (!inPath) {
			urls = this.vcsUrls();
		}

		for (var i=0, f; f = r[i]; i++) {
			// bespin uses the trailing slash '/' to indicate is a directory or not
			var isDir = (f.name.charAt(f.name.length-1) == '/');
			if (isDir)
				f.name = f.name.substring(0, f.name.length-1);
			// opus needs type (dir/file) in the FileTree
			f.type = (isDir ? "dir" : "file");

			if (urls && urls[f.name]) {
				f.vcsType = urls[f.name].type;
				f.vcsUrl = urls[f.name].url;
				f.displayName = f.name + " (" + urls[f.name].type + ")";
			}
		}
		return r;

	},
	listProjects: function(onSuccess) {
		if (onSuccess) {
			this.request('GET', '/file/list/', null, {onSuccess: onSuccess});
		} else {
			var result = this.request('GET', '/file/list/');
			return dojo.fromJson(result);
		}
	},
	write: function(inFilename, inString) {
		var result = this.request("PUT", "/file/at/" + inFilename, inString);
		return result;
	},
	read: function(inFilename, onSuccess, onFailure) {
		this.request("GET", "/file/at/" + inFilename, null, {onSuccess: onSuccess, onFailure: onFailure});
	},
	fileExists: function(inFilename) {
		var result = this.request("GET", "/file/exists/" + inFilename);
		return dojo.fromJson(result).success;
	},
	urlExists: function(inUrl) {
		var exists = false;
		var loaded = function() {
			exists = true;
		}
		dojo.xhrGet({url: inUrl, load: loaded, sync: true, failOk: true});
		return exists;
	},
	remove: function(inPath, onSuccess, onFailure) {
		this.request('DELETE', "/file/at/" + inPath, null, {onSuccess: onSuccess, onFailure: onFailure});
	},
	newProject: function(inProjectName) {
		this.request("POST", "/webos/newproject/" + inProjectName);
	},
	newScene: function(inProjectName, inSceneName, onSuccess, onFailure) {
		this.request("POST", "/webos/newscene/" + inProjectName + "/" + inSceneName, null,
			{onSuccess: onSuccess, onFailure: onFailure});
	},
	makePath: function(inPath) {
		this.request("PUT", "/file/at/" + inPath + "/");
	},
	getFileUrl: function(inFilename) {
		return this.baseUrl + "/file/at/" + inFilename;
	},
	getExportProjectUrl: function(inProjectName, inArchivetype) {
		return this.baseUrl + "/webos/project/export/" + inProjectName + "." + inArchivetype;
	},
	filesSearch: function(inSearchText, inProjectName, inFilePattern, onSuccess, onFailure) {
		var pattern = (inFilePattern ? " " : "") + "! ares.js";
		var data = {searchstring: inSearchText, project: inProjectName || "", filepattern: pattern};
		data = dojo.objectToQuery(data);
		this.request('POST', '/files/search', data, {onSuccess: onSuccess, onFailure: onFailure});
	},
	vcsKeygen: function(inPasswd, onSuccess, onFailure) {
		var data = (inPasswd ? "kcpass=" + escape(inPasswd) : null);
		this.request('POST', '/vcs/getkey/', data,
			{onSuccess: onSuccess, onFailure: onFailure});
	},
	vcsSetAuth: function(inProjectName, inData, onSuccess, onFailure) {
		this.request('POST', '/vcs/setauth/' + inProjectName + "/", inData,
			{onSuccess: onSuccess, onFailure: onFailure});
	},
	vcsKeychainExists: function() {
		var result = this.request("GET", "/vcs/keychainExists/");
		return dojo.fromJson(result).output;
	},
	vcsDeleteKeychain: function(onSuccess, onFailure) {
		this.request("GET", "/vcs/deleteKeychain/", null, {onSuccess: onSuccess, onFailure: onFailure});
	},
	vcsCheckout: function(inData, onSuccess, onFailure) {
		this.request("POST", "/vcs/clone/", inData,
			{onSuccess: onSuccess, onFailure: onFailure});
	},
	vcsNewProject: function(inProjectName, inData, onSuccess, onFailure) {
		this.request("POST", "/vcs/newproject/" + inProjectName, inData,
			{onSuccess: onSuccess, onFailure: onFailure});
	},
	vcsUrls: function() {
		var result = this.request("GET", "/vcs/urls/");
		return dojo.fromJson(result);
	},
	vcsCommand: function(inProject, inData, onSuccess, onFailure) {
		var url = '/vcs/command/' + inProject + '/';
		this.request("POST", url, dojo.toJson(inData),
			{onSuccess: onSuccess, onFailure: onFailure});
	},
	login: function(inUsername, inPassword, onSuccess, onFailure) {
		var url = "/webos/login/" + inUsername;
		this.request('POST', url, "password=" + escape(inPassword), {
			onSuccess: onSuccess,
			onFailure: onFailure
		});
	},
	logout: function(onSuccess) {
		var url = "/register/logout/";
		var s = onSuccess || function() {window.location.reload();};
		this.request('POST', url, null, {onSuccess: s});
	},
	getUserInfo: function() {
		var result = this.request("GET", "/register/userinfo/");
		var userInfo = eval("(" + result + ")");
		// opus uses the attribute 'user' to get the username
		userInfo.user = userInfo.username;
		return userInfo;
	},
	passwordChange: function(inUsername, inPassword, inNewPassword, onSuccess, onFailure) {
		var data = "username=" + inUsername + "&password=" + escape(inPassword) + "&newPassword=" + escape(inNewPassword);
		this.request("POST", "/webos/passwordchange/", data, {
			onSuccess: onSuccess,
			onFailure: onFailure
		});
	},
	/**
	 * Register a new user.
	 *
	 * @param inUsername is the username
	 * @param inPassword is the password
	 * @param inEmail is the email
	 */
	signup: function(inUsername, inPassword, inEmail, onSuccess, onFailure) {
		var url = "/webos/newuser/" + inUsername;
		var data = "password=" + escape(inPassword) + "&email=" + escape(inEmail);
		this.request('POST', url, data, {onSuccess: onSuccess, onFailure: onFailure});
	},
	getDocumentRoot: function() {
		return "/preview/at/";
	},
	getPreviewUrl: function(inProject) {
		// FIXME: this is an ugly url to show the user. it may not matter, but we could use cookie info to hide it.
		var systemPath = "/Ares/runtime/browser.js";
		return opus.server.getDocumentRoot() + inProject + "/index.html?app=" + systemPath;
	},
	makePackageLink: function(inName) {
		return "/webos/package/" + inName;
	},
	// opus library packages
	getAllPackages: function() {
		return [];
	},
	placePackage: function(inPackage) {
	}
};

