///</// <reference path='../file_storage.ts' />
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var ti_common;
(function (ti_common) {
    var file;
    (function (file_1) {
        var storage;
        (function (storage) {
            'use strict';
            var TI_WORKSPACE_SERVER = '';
            var TICloudConfig = (function () {
                function TICloudConfig() {
                }
                TICloudConfig.prototype.setWorkSpaceServer = function (workspaceURL) {
                    TI_WORKSPACE_SERVER = workspaceURL;
                };
                // no serivce, just config
                TICloudConfig.prototype.$get = function () {
                    return {};
                };
                return TICloudConfig;
            }());
            var TICloudFile = (function (_super) {
                __extends(TICloudFile, _super);
                function TICloudFile(name, $q, cloudStorage, size, mtime) {
                    if (size === void 0) { size = null; }
                    if (mtime === void 0) { mtime = null; }
                    _super.call(this, name, TICloudFile.TYPE, size);
                    this.$q = $q;
                    this.cloudStorage = cloudStorage;
                    this.mtime = mtime;
                    this.notReadyMessage = TICloudFile.NOT_READY_MESSAGE;
                }
                TICloudFile.prototype.getContents = function (contentType) {
                    var _this = this;
                    var waitForUploadifNeeded = this.uploadPromise ? this.uploadPromise : this.$q.resolve('');
                    if (!contentType) {
                        contentType = ti_common.file.ContentType.Text;
                    }
                    return waitForUploadifNeeded.then(function () {
                        return _this.cloudStorage.openFile(_this.name, contentType);
                    });
                };
                TICloudFile.prototype.delete = function () {
                    return this.cloudStorage.deleteFile(this.name);
                };
                // check to see if the name clashes with an existing file
                // if yes generate a new name
                TICloudFile.prototype.createNewNameIfNeeded = function () {
                    var _this = this;
                    var fileName = this.name;
                    var fileNameOnly = fileName.substring(0, fileName.indexOf('.'));
                    var fileExtensionOnly = fileName.substring(fileName.indexOf('.') + 1);
                    var fileFilter = new RegExp(fileNameOnly + '.*' + fileExtensionOnly);
                    var found = false;
                    return this.cloudStorage.getFileList(fileFilter).then(function (files) {
                        var biggestNum = 0;
                        _.each(files, function (fd) {
                            var file = fd.name;
                            if (file === fileName) {
                                found = true;
                            }
                            var regex = new RegExp(fileNameOnly + ' \\(\\d+\\)\\.' + fileExtensionOnly);
                            if (file.match(regex)) {
                                var idx1 = file.indexOf('(');
                                var idx2 = file.indexOf(')');
                                var numStr = file.substring(idx1 + 1, idx2);
                                var num = parseInt(numStr);
                                biggestNum = (biggestNum > num) ? biggestNum : num;
                            }
                        });
                        if (!found) {
                            return fileName;
                        }
                        else if (found && biggestNum === 0) {
                            return fileNameOnly + ' (1).' + fileExtensionOnly;
                        }
                        else {
                            biggestNum++;
                            return fileNameOnly + ' (' + biggestNum + ').' + fileExtensionOnly;
                        }
                    })
                        .then(function (newFileName) {
                        _this.name = newFileName;
                        _this.path = newFileName;
                        return newFileName;
                    });
                };
                TICloudFile.prototype.setContents = function (contents) {
                    var _this = this;
                    this.isReady = false;
                    return this.cloudStorage.saveFile(this.name, contents).then(function (message) {
                        _this.isReady = true;
                        return message;
                    });
                };
                TICloudFile.prototype.setDomFileContents = function (domFile) {
                    var _this = this;
                    this.isReady = false;
                    // restrict file to under 50MB
                    if (domFile.size > 52428800) {
                        this.uploadPromise = this.$q.reject('Exceeds file size limit');
                    }
                    else {
                        var deferredUpload = this.$q.defer();
                        this.uploadPromise = deferredUpload.promise;
                        this.uploadPromise = this.readDomFile(domFile)
                            .then(function (contents) {
                            return _this.setContents(new Blob([contents]));
                        });
                    }
                    return this.uploadPromise;
                };
                TICloudFile.prototype.getDisplayTime = function () {
                    if (this.mtime) {
                        return this.mtime.substring(0, this.mtime.length - 5).replace('T', ' ');
                    }
                    else {
                        return 'new';
                    }
                };
                TICloudFile.prototype.readDomFile = function (domFile) {
                    var deferred = this.$q.defer();
                    var r = new FileReader();
                    r.onload = function (e) {
                        var contents = e.target.result;
                        var bytesArray = new Uint8Array(contents);
                        deferred.resolve(bytesArray);
                    };
                    r.readAsArrayBuffer(domFile);
                    return deferred.promise;
                };
                TICloudFile.NOT_READY_MESSAGE = 'Uploading';
                TICloudFile.TYPE = 'TICloudFile';
                return TICloudFile;
            }(ti_common.file.File));
            function createUrl(name) {
                return TI_WORKSPACE_SERVER + '/' + encodeURIComponent(name);
            }
            // This service is only meant to be used internally to build other services 
            // such as implementing File ...
            var TICloudFileStorage = (function () {
                function TICloudFileStorage($http, $q) {
                    this.$http = $http;
                    this.$q = $q;
                }
                TICloudFileStorage.prototype.getAppDataDirectory = function () {
                    return this.$q(function (resolve, reject) {
                        //create a prefereces.inf file on the local workspace, filter this file out from other cloud file browsers.
                        resolve('./');
                    });
                };
                TICloudFileStorage.prototype.saveFile = function (filename, contents) {
                    var data;
                    var url = createUrl(filename);
                    var contentType;
                    if (contents instanceof Blob) {
                        contentType = ti_common.file.ContentType.Blob;
                    }
                    else {
                        contentType = ti_common.file.ContentType.Text;
                    }
                    return this.$http.put(url, contents, {
                        headers: {
                            'Content-Type': file_1.ContentTypeHeaderLookup[contentType]
                        },
                        transformRequest: []
                    })
                        .then(function () {
                        return 'Success';
                    });
                };
                TICloudFileStorage.prototype.openFile = function (filename, contentType) {
                    // structured this way to work around type script compiler warnings
                    // doesn't deal well with exceptions
                    var fail = function (response) {
                        throw new Error("Could not open file " + filename + " : " + response.statusText);
                    };
                    var configObj = {};
                    configObj.responseType = file_1.ResponseTypeConfigLookup[contentType];
                    return this.$http.get(createUrl(filename), configObj)
                        .then(function (response) {
                        return response.data;
                    }).catch(fail);
                };
                TICloudFileStorage.prototype.deleteFile = function (filename) {
                    return this.$http.delete(createUrl(filename)).then(function () { return true; });
                };
                TICloudFileStorage.prototype.fileExists = function (filename) {
                    var url = createUrl(filename) + '?command=exists';
                    var config = {};
                    config.params = {
                        'filename': filename
                    };
                    return this.$http.get(url, config).then(function (response) {
                        return JSON.parse(response.data);
                    });
                };
                TICloudFileStorage.prototype.getFileList = function (x) {
                    var _this = this;
                    var url = TI_WORKSPACE_SERVER + '?command=list';
                    if (x instanceof RegExp) {
                        var filterRegex = x;
                        if (filterRegex) {
                            var formattedFilter = encodeURIComponent(filterRegex.source);
                            url += '&filter=' + formattedFilter;
                        }
                        return this.$http.get(url).then(function (response) {
                            var filesList = JSON.parse(response.data);
                            filesList = _.map(filesList, function (fd) {
                                return new TICloudFile(fd.name, _this.$q, _this, fd.size, fd.mtime);
                            });
                            return filesList;
                        });
                    }
                    else if (typeof x === 'string') {
                        return this.$http.get(url).then(function (response) {
                            var filesList = JSON.parse(response.data);
                            var retFileList = [];
                            filesList = _.map(filesList, function (fd) {
                                if (_this.isAcceptableExtension(fd.name, x)) {
                                    retFileList.push(new TICloudFile(fd.name, _this.$q, _this, fd.size, fd.mtime));
                                }
                            });
                            return retFileList;
                        });
                    }
                };
                TICloudFileStorage.prototype.isAcceptableExtension = function (filename, extensions) {
                    var extArray = extensions.split(',');
                    var ret = false;
                    _.each(extArray, function (ext) {
                        var extRegex = new RegExp(ext, 'i');
                        if (filename.match(extRegex)) {
                            ret = true;
                            return;
                        }
                    });
                    return ret;
                };
                TICloudFileStorage.prototype.upload = function (domFile) {
                    var newFile = new TICloudFile(domFile.name, this.$q, this, domFile.size);
                    newFile.createNewNameIfNeeded()
                        .then(function () {
                        newFile.setDomFileContents(domFile);
                    });
                    return newFile;
                };
                TICloudFileStorage.$inject = ['$http', '$q'];
                return TICloudFileStorage;
            }());
            var TIFileFactory = (function () {
                function TIFileFactory($q, ticCloudStorage) {
                    this.$q = $q;
                    this.ticCloudStorage = ticCloudStorage;
                }
                TIFileFactory.prototype.create = function (path) {
                    return new TICloudFile(path, this.$q, this.ticCloudStorage);
                };
                TIFileFactory.prototype.createFromJSON = function (obj) {
                    if (obj.type !== TICloudFile.TYPE) {
                        throw obj.type + ' is not of the type of ' + TICloudFile.TYPE;
                    }
                    return new TICloudFile(obj.name, this.$q, this.ticCloudStorage, obj.size, null);
                };
                TIFileFactory.$inject = ['$q', 'ticFileStorage'];
                return TIFileFactory;
            }());
            angular.module('ti_common').service('ticFileStorage', TICloudFileStorage);
            // File factory in the cloud case
            angular.module('ti_common').service('ticFileFactory', TIFileFactory);
            angular.module('ti_common').provider('ticPlatformConfig', TICloudConfig);
        })(storage = file_1.storage || (file_1.storage = {}));
    })(file = ti_common.file || (ti_common.file = {}));
})(ti_common || (ti_common = {}));
