]> git.parisson.com Git - timeside.git/commitdiff
update UI from Telemeta rev539 to rev638
authoryomguy <yomguy@parisson.com>
Tue, 15 Mar 2011 15:15:54 +0000 (15:15 +0000)
committeryomguy <yomguy@parisson.com>
Tue, 15 Mar 2011 15:15:54 +0000 (15:15 +0000)
16 files changed:
timeside/ui/css/timeside.css
timeside/ui/skins/lab/img/controlbg.png
timeside/ui/skins/lab/img/forward.png
timeside/ui/skins/lab/img/pause.png
timeside/ui/skins/lab/img/play.png
timeside/ui/skins/lab/img/rewind.png
timeside/ui/skins/lab/img/setmarker.png
timeside/ui/skins/lab/style.css
timeside/ui/src/controller.js
timeside/ui/src/core.js
timeside/ui/src/marker.js
timeside/ui/src/markermap.js
timeside/ui/src/player.js
timeside/ui/src/ruler.js
timeside/ui/src/timeside.js
timeside/ui/src/util.js

index cadc79ad264a19a8a56f3130bbdac49c0b289456..014ae61975a43ea40cc3cfa8497a20dc0792b7cd 100755 (executable)
     position: relative;
 }
 
+.ts-image-container {
+    background-color: #000000;
+}
+
 .ts-player .ts-wave .ts-image {
     position: absolute;
     left: 0;
index 57840d01af9af5dd81c31fc711483239d13d6580..edaf9fc9a90964d3dbbff9f90318c6206892d7a4 100755 (executable)
Binary files a/timeside/ui/skins/lab/img/controlbg.png and b/timeside/ui/skins/lab/img/controlbg.png differ
index 86485d0d222533ed1f5f25a9c796eeeed14a3dd3..66f623273efdc2568362bd4546c691dcd4cc4e46 100755 (executable)
Binary files a/timeside/ui/skins/lab/img/forward.png and b/timeside/ui/skins/lab/img/forward.png differ
index d09ad51cf397949151fa48d656b82e96de1375f1..103357f00a8c821343bb9f0d7dbec0070db2e6cf 100755 (executable)
Binary files a/timeside/ui/skins/lab/img/pause.png and b/timeside/ui/skins/lab/img/pause.png differ
index ccb87e877c2bd90bf0d3cd8cbe205d7171be559c..9a89b4f1ac0bd62d36689a5dbbdae06170d9dad1 100755 (executable)
Binary files a/timeside/ui/skins/lab/img/play.png and b/timeside/ui/skins/lab/img/play.png differ
index ec45b3852a6ef7409015ce54eb4bb689af4af9be..550263fda609c58edd016c1110147b8a1f5116a5 100755 (executable)
Binary files a/timeside/ui/skins/lab/img/rewind.png and b/timeside/ui/skins/lab/img/rewind.png differ
index b642e824e9cdcfccf9eeccb5facdecd3643770df..af79be53914a4ea08abfa20cbb8550a43f81177b 100644 (file)
Binary files a/timeside/ui/skins/lab/img/setmarker.png and b/timeside/ui/skins/lab/img/setmarker.png differ
index 5dcd35391c6459d6b69e6a02086423a3c365f00c..003f5a66e179b7e6d1c41f84f0661c675dc522b1 100755 (executable)
@@ -2,7 +2,7 @@
   background: #3c4251;
   padding-top: 10px;
   padding-bottom: 10px;
-  border: dotted #b2b2b2 1px;
+  border: solid #b2b2b2 1px;
 }
 
 .ts-skin-lab .ts-player .ts-viewer {
 .ts-skin-lab .ts-player .ts-control {
     background: url('img/controlbg.png');
     height: 28px;
-    border-top: dotted #b2b2b2 1px;
+/*     border-top: dotted #b2b2b2 1px; */
 }
 
 .ts-skin-lab .ts-player .ts-control .ts-layout {
     margin-left: 12px;
     margin-right: 12px;
-    padding-top: 4px;
+    padding-top: 0px;
 }
 
 .ts-skin-lab .ts-player .ts-control .ts-playback a {
     display: block;
     float: left;
-    width: 21px;
-    padding: 21px 0 0 0;
+    width: 30px;
+    padding: 28px 0 0 0;
     overflow: hidden;
     height: 0px !important; 
-    height /**/:21px; /* for IE5/Win only */
-    margin-right: 1px;
+    height /**/:28px; /* for IE5/Win only */
+    margin-right: 0px;
 }
 
 .ts-skin-lab .ts-player .ts-control .ts-playback a:hover {
-    background-position: 0 -21px;
+    background-position: 0 -28px;
 }
 
 .ts-skin-lab .ts-player .ts-control .ts-playback .ts-play {
 .ts-skin-lab .ts-player .ts-marker-control .ts-set-marker {
     display: block;
     width: 89px;
-    padding: 21px 0 0 0;
+    padding: 28px 0 0 0;
     overflow: hidden;
     height: 0px !important; 
-    height /**/:21px; /* for IE5/Win only */
+    height /**/:28px; /* for IE5/Win only */
     background-image: url('img/setmarker.gif');
     margin: 5px auto 0 auto;
 }
     height: 30px;
 }
 
+
+
index ba0870be22f94bf675dbb41083bd6ae94bedc06b..ddd0d3e8876af04813f16fe7a62e7631a596dbe9 100644 (file)
 
 TimeSide(function($N) {
 
-$N.Class.create("Controller", $N.Core, {
-
-    initialize: function($super, cfg) {
-        $super();
-        this.configure(cfg, {
-            player: null,
-            soundProvider: null,
-            map: null
-        });
-        if (this.cfg.player && !$N.isInstanceOf(this.cfg.player, 'Player')) {
-            this.cfg.player = new $N.Player(this.cfg.player);
-        }
-        this._setupPlayer();
-    },
+    $N.Class.create("Controller", $N.Core, {
+
+        initialize: function($super, cfg) {
+            $super();
+            this.configure(cfg, {
+                player: null,
+                soundProvider: null,
+                map: null,
+                divmarkers:[]
+            });
+            if (this.cfg.player && !$N.isInstanceOf(this.cfg.player, 'Player')) {
+                this.cfg.player = new $N.Player(this.cfg.player);
+            }
+            this._setupPlayer();
+        //setting the divmarkers
+        //this.cfg.map.observe('add')
+            
+        },
 
-    _setupPlayer: function() {
-        this.cfg.player
+        _setupPlayer: function() {
+            
+            this.cfg.player
             .setSoundProvider(this.cfg.soundProvider)
             .setMarkerMap(this.cfg.map)
             .observe('play', $N.attachFunction(this.cfg.soundProvider, this.cfg.soundProvider.play))
             .observe('pause', $N.attachFunction(this.cfg.soundProvider, this.cfg.soundProvider.pause))
             .observe('move', this.attach(this._onMove))
             .observe('markeradd', this.attach(this._onMarkerAdd))
+            //player markermove listens for changes of ruler markermove which listens
+            //foir changes in each marker move
             .observe('markermove', this.attach(this._onMarkerMove))
+            
             .draw();
-    },
+            this.loadHTTP();
 
-    _onMove: function(e, data) {
-        this.cfg.soundProvider.seek(data.offset);
-    },
+            this.cfg.map.observe('add',this.attach(this._onMarkerMapAdd));
+            this.cfg.map.observe('remove',this.attach(this._onMarkerMapRemove));
+            this.cfg.map.observe('moved',this.attach(this._onMarkerMapMoved));
+            
+        },
 
-    _onMarkerMove: function(e, data) {
-        if (this.cfg.map) {
-            this.cfg.map.move(this.cfg.map.byId(data.id), data.offset);
-        }
-    },
 
-    _onMarkerAdd: function(e, data) {
-        if (this.cfg.map) {
-            this.cfg.map.add(data.offset, 'marker at ' + data.offset);
+        _onMove: function(e, data) {
+            this.cfg.soundProvider.seek(data.offset);
+        },
+
+        //called whenever a marker is moved in the ruler BUT NOT in the map
+        _onMarkerMove: function(e, data) {
+            if (this.cfg.map) {
+                $N.Util.selectMarkerTab(); //defined in utils.js
+                this.cfg.map.move(data.index, data.offset);
+            //this will fire the method below
+            }
+        },
+
+        _onMarkerMapMoved:function(e, data){
+            var from = data.fromIndex;
+            var to = data.toIndex;
+            if(from===to){
+                //just update the div in order to show the new time offset
+                //and start edit
+                this.cfg.divmarkers[from].setIndex(to);
+                return;
+            }
+            this.cfg.player.ruler.move(from,to);
+            var m = this.cfg.divmarkers.splice(from,1)[0]; //remove
+            this.cfg.divmarkers.splice(to,0,m); //add
+            this.updateIndices(from,to);
+        },
+
+        //called whenever a marker is added to the ruler BUT NOT in the map
+        _onMarkerAdd: function(e, data) {
+            if (this.cfg.map) {
+                $N.Util.selectMarkerTab(); //defined in mediaitem|_detail.html
+                var idx = this.cfg.map.add(data.offset); //this will call the method below _onMarkerMapAdd,
+                //which btw adds a new div to divmarkers
+                //now update the indices for the div (which also sets the event bindings as clicks etc...
+                this.updateIndices(idx);
+            }
+        },
+        //fired from markermap, attached as listener above in
+        //this.cfg.map.observe('add',this.attach(this._onMarkerMapAdd));
+        //this method basically adds the html elements, but updateIndices must be called elsewhere after this function
+        //(see _onMarkerAdd and loadHTTP)
+        _onMarkerMapAdd: function(e, data) {
+            if (this.cfg.map) {
+                //$N.Util.selectMarkerTab(); //defined in mediaitem|_detail.html
+                //this.refreshMarkersText(this.cfg.map);
+                //var idx = this.cfg.map.add(data.offset);
+                //alert('df');
+                var idx = data.index;
+                var divMarker = new $N.DivMarker(this.cfg.map);
+                this.cfg.divmarkers.splice(idx,0, divMarker);
+                this.cfg.player.ruler.add(data.marker, idx);
+            }
+        },
+
+        //fired from markermap, attached as listener above in
+        //this.cfg.map.observe('add',this.attach(this._onMarkerMapAdd));
+        _onMarkerMapRemove: function(e, data) {
+            if (this.cfg.map) {
+                //$N.Util.selectMarkerTab(); //defined in mediaitem|_detail.html
+                //this.refreshMarkersText(this.cfg.map);
+                //var idx = this.cfg.map.add(data.offset);
+                //alert('df');
+                var idx = data.index;
+                var divRemoved = this.cfg.divmarkers.splice(idx,1)[0]; //there is only one element removed
+                divRemoved.remove();
+                this.cfg.player.ruler.remove(idx);
+                this.updateIndices(idx);
+            }
+        },
+
+        updateIndices: function(from, to){
+            if(from===undefined || from==null){
+                from = 0;
+            }
+            var len = this.cfg.divmarkers.length-1;
+            if(from>len){
+                //it might happen when we remove the last element
+                //suppose [0,1,2], we remove [2] then we call
+                //updateIndices[2] but array till 1 (there is nothing to update)
+                return;
+            }
+            if(to==undefined || to ==null){
+                to = len;
+            }
+            if(to<from){
+                var tmp = to;
+                to=from;
+                from=tmp;
+            }
+            for(var i = from; i <= to; i++){
+                this.cfg.divmarkers[i].setIndex(i);
+            }
+            this.cfg.player.ruler.updateMarkerIndices(from,to);
+        },
+
+
+        loadHTTP: function(){
+
+            //itemid is the item (spund file) name
+            var sPath = window.location.pathname;
+            //remove last "/" or last "/#", if any...
+            sPath = sPath.replace(/\/#*$/,"");
+            var itemid = sPath.substring(sPath.lastIndexOf('/') + 1);
+
+            //WARNING: use single quotes for the whole string!!
+            //see http://stackoverflow.com/questions/4809157/i-need-to-pass-a-json-object-to-a-javascript-ajax-method-for-a-wcf-call-how-can
+            var data2send = '{"id":"jsonrpc","params":["'+itemid+'"], "method":"telemeta.get_markers","jsonrpc":"1.0"}';
+            var map = this.cfg.map;
+            var update = this.updateIndices;
+            var me = this;
+            $.ajax({
+                type: "POST",
+                url: '/json/',
+                contentType: "application/json",
+                data: data2send,
+                dataType: "json",
+                success: function(data) {
+                    if(data){
+                        if(data.result && data.result.length>0){
+                            var result = data.result;
+                            
+                            for(var i =0; i< result.length; i++){
+                                map.add(result[i]);
+                            }
+                            //we call now updateindices
+                            update.apply(me);
+                            
+                        }
+                        
+                    }
+                    //We call mediaitem_detail.setUpTabs from controller once all markers have been loaded
+                    //this because setLabelDescription, which sets the label text according to the div width,
+                    //needs to have all elements visible.
+                    $N.Util.setUpTabs();
+                //setUpTabs(); //which hides the marker div. Call with argument 1 to set up marker div
+                //as visible as startup
+                }
+            });
+        //var g = 9;
         }
-    }
 
-});
+    
+
+    });
 
-$N.notifyScriptLoad();
+    $N.notifyScriptLoad();
 
 });
index 3f48121454086bf5a37a8cd12302cf56a39303c3..e86b691766f0e2a521fd0ccdfdb9c9f4d65bec51 100644 (file)
 
 TimeSide(function($N, $J) {
 
-$N.extend = function(destination, source) {
-  for (var property in source)
-    destination[property] = source[property];
-  return destination;
-};
-
-$N.objectKeys = function(object) {
-    var keys = [];
-    for (var property in object)
-      keys.push(property);
-    return keys;
-};
-
-$N.argumentNames = function(method) {
-    var names = method.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
-      .replace(/\s+/g, '').split(',');
-    return names.length == 1 && !names[0] ? [] : names;
-};  
-
-$N.argsToArray = function(args) {
-    var length = args.length || 0, result = new Array(length);
-    while (length--) result[length] = args[length];
-    return result;
-};
-
-$N.wrapFunction = function(wrapper, method) {
-    return function() {
-      var args = $N.argsToArray(arguments);
-      return wrapper.apply(this, [$N.attachFunction(this, method)].concat(args)); 
-    }
-};
-$N.attachFunction = function() {
-    if (arguments.length < 3 && (typeof arguments[1] == 'undefined')) return arguments[0];
-    var args = $N.argsToArray(arguments);
-    var object = args.shift();
-    var method = args.shift();
-    return function() {
-      var _args = $N.argsToArray(arguments);
-      return method.apply(object, args.concat(_args));
-    }
-};
+    $N.extend = function(destination, source) {
+        for (var property in source){
+            destination[property] = source[property];
+        }
+        return destination;
+    };
 
-$N.attachAsEventListener = function() {
-    var args = $N.argsToArray(arguments), object = args.shift();
-    var method = args.shift();
-    return function(event) {
-      return method.apply(object, [event || window.event].concat(args));
-    }
-};
+    $N.objectKeys = function(object) {
+        var keys = [];
+        for (var property in object){
+            keys.push(property);
+        }
+        return keys;
+    };
+
+    $N.argumentNames = function(method) {
+        var names = method.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
+        .replace(/\s+/g, '').split(',');
+        return names.length == 1 && !names[0] ? [] : names;
+    };
+
+    $N.argsToArray = function(args) {
+        var length = args.length || 0, result = new Array(length);
+        while (length--){
+            result[length] = args[length];
+        }
+        return result;
+    };
 
-$N.isInstanceOf = function(obj, className) {
-    if (typeof obj == 'object' && obj.__class__) {
-        var c = obj.__class__;
-        if (c.__name__ == className) {
-            return true;
+    $N.wrapFunction = function(wrapper, method) {
+        return function() {
+            var args = $N.argsToArray(arguments);
+            return wrapper.apply(this, [$N.attachFunction(this, method)].concat(args));
         }
-        while (c = c.__super__) {
+    };
+    $N.attachFunction = function() {
+        if (arguments.length < 3 && (typeof arguments[1] == 'undefined')){
+            return arguments[0];
+        }
+        var args = $N.argsToArray(arguments);
+        var object = args.shift();
+        var method = args.shift();
+        return function() {
+            var _args = $N.argsToArray(arguments);
+            return method.apply(object, args.concat(_args));
+        }
+    };
+
+    $N.attachAsEventListener = function() {
+        var args = $N.argsToArray(arguments), object = args.shift();
+        var method = args.shift();
+        return function(event) {
+            return method.apply(object, [event || window.event].concat(args));
+        }
+    };
+
+    $N.isInstanceOf = function(obj, className) {
+        if (typeof obj == 'object' && obj.__class__) {
+            var c = obj.__class__;
             if (c.__name__ == className) {
                 return true;
             }
+            while (c = c.__super__) {
+                if (c.__name__ == className) {
+                    return true;
+                }
+            }
         }
+        return false;
     }
-    return false;
-}
-
-$N.Class = {
-  create: function() {
-    var parent = null, className = null;
-    var properties = $N.argsToArray(arguments)
-    if (typeof properties[0] == "string")
-      className = properties.shift();
-    if (typeof properties[0] == "function")
-      parent = properties.shift();
-    
-    function klass() {
-      this.initialize.apply(this, arguments);
-    }
+
+    $N.Class = {
+        create: function() {
+            var parent = null, className = null;
+            var properties = $N.argsToArray(arguments)
+            if (typeof properties[0] == "string"){
+                className = properties.shift();
+            }
+            if (typeof properties[0] == "function"){
+                parent = properties.shift();
+            }
     
-    $N.extend(klass, $N.Class.Methods);
-    klass.__name__ = className;
-    klass.__super__ = parent;
-    klass.__subclasses__ = [];
+            function klass() {
+                this.initialize.apply(this, arguments);
+            }
+            //Merge the contents of $N.Class.Methods into klass:
+            $N.extend(klass, $N.Class.Methods);
+            klass.__name__ = className;
+            klass.__super__ = parent;
+            klass.__subclasses__ = [];
     
-    if (parent) {
-      var subclass = function() { };
-      subclass.prototype = parent.prototype;
-      klass.prototype = new subclass;
-      parent.__subclasses__.push(klass);
-    }
+            if (parent) {
+                var subclass = function() { };
+                subclass.prototype = parent.prototype;
+                klass.prototype = new subclass;
+                parent.__subclasses__.push(klass);
+            }
     
-    klass.prototype.__class__ = klass;
-    for (var i = 0; i < properties.length; i++)
-      klass.addMethods(properties[i]);
+            klass.prototype.__class__ = klass;
+            for (var i = 0; i < properties.length; i++){
+                klass.addMethods(properties[i]);
+            }
       
-    if (!klass.prototype.initialize)
-      klass.prototype.initialize = function () {};
+            if (!klass.prototype.initialize){
+                klass.prototype.initialize = function () {};
+
+            }
     
-    klass.prototype.constructor = klass;
+            klass.prototype.constructor = klass;
    
-    if (className) {
-        $N[className] = klass;
-    }
-    return klass;
-  }
-};
+            if (className) {
+                $N[className] = klass;
+            }
+            return klass;
+        }
+    };
  
-$N.Class.Methods = {
-  addMethods: function(source) {
-    var ancestor   = this.__super__ && this.__super__.prototype;
-    var properties = $N.objectKeys(source);
-    
-    if (!$N.objectKeys({ toString: true }).length)
-      properties.push("toString", "valueOf");
+    $N.Class.Methods = {
+        addMethods: function(source) {
+            var ancestor   = this.__super__ && this.__super__.prototype;
+            var properties = $N.objectKeys(source);
     
-    for (var i = 0, length = properties.length; i < length; i++) {
-      var property = properties[i], value = source[property];
-      if (ancestor && (typeof value == 'function') &&
-          $N.argumentNames(value)[0] == "$super") {
-        var method = value;
-        value = $N.wrapFunction(method, (function(m) {
-          return function() { return ancestor[m].apply(this, arguments) };
-        })(property));
+            if (!$N.objectKeys({
+                toString: true
+            }).length){
+                properties.push("toString", "valueOf");
+            }
+            for (var i = 0, length = properties.length; i < length; i++) {
+                var property = properties[i], value = source[property];
+                if (ancestor && (typeof value == 'function') &&
+                    $N.argumentNames(value)[0] == "$super") {
+                    var method = value;
+                    value = $N.wrapFunction(method, (function(m) {
+                        return function() {
+                            return ancestor[m].apply(this, arguments)
+                        };
+                    })(property));
  
-        value.valueOf = $N.attachFunction(method, method.valueOf);
-        value.toString = $N.attachFunction(method, method.toString);
-      }
-      this.prototype[property] = value;
-    }
+                    value.valueOf = $N.attachFunction(method, method.valueOf);
+                    value.toString = $N.attachFunction(method, method.toString);
+                }
+                this.prototype[property] = value;
+            }
     
-    return this;
-  }
-};
+            return this;
+        }
+    };
  
-$N.Core = $N.Class.create("Core", {
-    eventContainer: null,
-    eventPrefix: '',
-    cfg: {},
-
-    initialize: function() {
-        this.debug("new instance");
-        $N.registerInstance(this);
-        this.eventContainer = $J('<div/>');
-        this.forwardEvent = this.attach(this._forwardEvent);
-    },
-
-    free: function() {
-        this.eventContainer = null;
-    },
-
-    configure: function(config, defaults) {
-        if (!config)
-            config = {};
-        for (k in defaults) {
-            var value = null, flags = [];
-
-            if (defaults[k] && typeof defaults[k][0] !== 'undefined') {
-                value = defaults[k][0];
-                if (defaults[k][1]) {
-                    flags = defaults[k][1].split(",");
-                }
-            } else {
-                value = defaults[k];
+    $N.Core = $N.Class.create("Core", {
+        eventContainer: null,
+        eventPrefix: '',
+        cfg: {},
+
+        initialize: function() {
+            this.debug("new instance");
+            $N.registerInstance(this);
+            this.eventContainer = $J('<div/>');
+            this.forwardEvent = this.attach(this._forwardEvent);
+        },
+
+        free: function() {
+            this.eventContainer = null;
+        },
+
+        configure: function(config, defaults) {
+            if (!config){
+                config = {};
+
             }
+            for (k in defaults) {
+                var value = null, flags = [];
 
-            if (typeof config[k] !== 'undefined') 
-                value = config[k];
+                if (defaults[k] && typeof defaults[k][0] !== 'undefined') {
+                    value = defaults[k][0];
+                    if (defaults[k][1]) {
+                        flags = defaults[k][1].split(",");
+                    }
+                } else {
+                    value = defaults[k];
+                }
 
-            var source = this;
-            $J(flags).each(function(i, flag) {
-                switch (flag) {
-                    case 'required':
-                        if (value === null)
-                            throw new $N.RequiredOptionError(source, k);
-                        break;
-                        /*
+                if (typeof config[k] !== 'undefined'){
+                    value = config[k];
+                }
+
+                var source = this;
+                $J(flags).each(function(i, flag) {
+                    switch (flag) {
+                        case 'required':
+                            if (value === null)
+                                throw new $N.RequiredOptionError(source, k);
+                            break;
+                    /*
                     case 'element':
                         value = $J(value);
                         break;
                         */
 
-                }
-            });
+                    }
+                });
 
-            this.cfg[k] = value;
-        }
-        return this;
-    },
-
-    observe: function(eventName, handler) {
-        this.eventContainer.bind(this.eventPrefix + eventName, handler);
-        return this;
-    },
-
-    fire: function(eventName, data) {
-        if (!data)
-            data = {};
-        this.eventContainer.trigger(this.eventPrefix + eventName, data);
-        return this;
-    },
-
-    _forwardEvent: function(e, data) {
-        if (!data)
-            data = {};
-        this.eventContainer.trigger(e.type, data);
-        return this;
-    },
-
-    _textWidth: function(text, fontSize) {
-        var ratio = 3/5;
-        return text.length * ratio * fontSize;
-    },
-
-    debug: function(message) {
-        if ($N.debugging && typeof console != 'undefined' && console.log) {
-            console.log('TimeSide.' + this.__class__.__name__ + ': ' + message);
-        }
-    },
+                this.cfg[k] = value;
+            }
+            return this;
+        },
 
-    attach: function(method) {
-        return $N.attachFunction(this, method);
-    },
+        observe: function(eventName, handler) {
+            this.eventContainer.bind(this.eventPrefix + eventName, handler);
+            return this;
+        },
 
-    attachWithEvent: function(method) {
-        return $N.attachAsEventListener(this, method);
-    },
+        fire: function(eventName, data) {
+            if (!data){
+                data = {};
 
-    uniqid: function() {
-        d = new Date();
-        return new String(d.getTime() + '' + Math.floor(Math.random() * 1000000)).substr(0, 18);
-    }
-});
+            }
+            this.eventContainer.trigger(this.eventPrefix + eventName, data);
+            return this;
+        },
+
+        _forwardEvent: function(e, data) {
+            if (!data){
+                data = {};
 
-$N.Class.create("Exception", {
-    _source: null,
-    _message: null,
+            }
+            this.eventContainer.trigger(e.type, data);
+            return this;
+        },
+
+        _textWidth: function(text, fontSize) {
+            var ratio = 3/5;
+            return text.length * ratio * fontSize;
+        },
+
+        debug: function(message) {
+            if ($N.debugging && typeof console != 'undefined' && console.log) {
+                console.log('TimeSide.' + this.__class__.__name__ + ': ' + message);
+            }
+        },
+
+        attach: function(method) {
+            return $N.attachFunction(this, method);
+        },
+
+        attachWithEvent: function(method) {
+            return $N.attachAsEventListener(this, method);
+        },
+
+        uniqid: function() {
+            d = new Date();
+            return new String(d.getTime() + '' + Math.floor(Math.random() * 1000000)).substr(0, 18);
+        }
+    });
+
+    $N.Class.create("Exception", {
+        _source: null,
+        _message: null,
 
-    initialize: function(source, message) {
-        this._source = source;
-        this._message = message;
-    },
-    toString: function() {
-        return this.__class__.__name__ + " from TimeSide." + this._source.__class__.__name__
+        initialize: function(source, message) {
+            this._source = source;
+            this._message = message;
+        },
+        toString: function() {
+            return this.__class__.__name__ + " from TimeSide." + this._source.__class__.__name__
             + ": " + this._message;
-    }
-});
+        }
+    });
 
-$N.Class.create("RequiredOptionError", $N.Exception, {
-    initialize: function($super, source, optionName) {
-        $super(source, "missing '" + optionName + "' required option");
-    }
-});
+    $N.Class.create("RequiredOptionError", $N.Exception, {
+        initialize: function($super, source, optionName) {
+            $super(source, "missing '" + optionName + "' required option");
+        }
+    });
 
-$N.Class.create("RequiredArgumentError", $N.Exception, {
-    initialize: function($super, source, optionName) {
-        $super(source, "missing '" + optionName + "' required argument");
-    }
-});
+    $N.Class.create("RequiredArgumentError", $N.Exception, {
+        initialize: function($super, source, optionName) {
+            $super(source, "missing '" + optionName + "' required argument");
+        }
+    });
 
-$N.notifyScriptLoad();
+    $N.notifyScriptLoad();
 
 });
index 32f74430edc95117b0f84f1758b8c13d9d28b292..bd54550e7cb5141b38b07c3d5636d5bc38e4e222 100644 (file)
@@ -7,55 +7,67 @@
 
 TimeSide(function($N, $J) {
 
-$N.Class.create("Marker", $N.Core, {
-    id: null,
-    painter: null,
-    visible: false,
-    position: 0,
-    label: null,
-    blinking: false,
-    nodes: null,
-    mouseDown: false,
-    blinkAnimation: null,
-
-    initialize: function($super, cfg) {
-        $super();
-        this.configure(cfg, {
-            rulerLayout: [null, 'required'],
-            viewer: [null, 'required'],
-            fontSize: 10,
-            zIndex: null,
-            className: [null, 'required'],
-            id: null,
-            tooltip: null
-        });
-        this.cfg.rulerLayout = $J(this.cfg.rulerLayout);
-        this.cfg.viewer = $J(this.cfg.viewer);
-
-        this.id = cfg.id;
-        this.width = this.cfg.viewer.width();
-        this.painter = new jsGraphics(this.cfg.viewer.get(0));
-        this._create();
-        this._observeMouseEvents();
-    },
-
-    free: function($super) {
-        this.cfg.rulerLayout = null;
-        this.cfg.viewer = null;
-        $super();
-    },
-
-    clear: function() {
-        this.painter.clear();
-        $J(this.painter.cnv).remove();
-        this.label.remove();
-        return this;
-    },
-
-    _create: function() {
-        this.debug('create marker');
-        var y = this.cfg.rulerLayout.find('.' + $N.cssPrefix + 'label').outerHeight();
-        this.label = $J('<a/>')
+    $N.Class.create("Marker", $N.Core, {
+        id: null,
+        painter: null,
+        visible: false,
+        position: 0,
+        label: null,
+        blinking: false,
+        nodes: null,
+        mouseDown: false,
+        blinkAnimation: null,
+
+        initialize: function($super, cfg) {
+            $super();
+            //sets the fields required???? see ruler.js createPointer
+            this.configure(cfg, {
+                rulerLayout: [null, 'required'],
+                viewer: [null, 'required'],
+                fontSize: 10,
+                zIndex: null,
+                className: [null, 'required'],
+                index: null,
+                tooltip: null,
+                canMove: false
+            });
+            this.cfg.rulerLayout = $J(this.cfg.rulerLayout);
+            this.cfg.viewer = $J(this.cfg.viewer);
+
+            this.width = this.cfg.viewer.width();
+            this.painter = new jsGraphics(this.cfg.viewer.get(0));
+            this._create();
+            if(this.cfg.canMove){
+                this._observeMouseEvents();
+            }
+            //if it is the pointer, cfg.index is undefined
+            if(cfg.index !== undefined && cfg.className!='pointer'){
+                this.setIndex(cfg.index);
+            }
+        },
+
+        setIndex: function(index){
+            this.index = index;
+            this.setText(index+1);
+        },
+
+        free: function($super) {
+            this.cfg.rulerLayout = null;
+            this.cfg.viewer = null;
+            $super();
+        },
+
+        clear: function() {
+            this.painter.clear();
+            $J(this.painter.cnv).remove();
+            this.label.remove();
+            return this;
+        },
+
+        _create: function() {
+            this.debug('create marker');
+            var y = this.cfg.rulerLayout.find('.' + $N.cssPrefix + 'label').outerHeight();
+            this.label = $J('<a/>')
             .css({
                 display: 'block',
                 width: '10px', 
@@ -70,150 +82,178 @@ $N.Class.create("Marker", $N.Core, {
             .append('<span />')
             .hide();
 
-        if (this.cfg.tooltip)
-            this.label.attr('title', this.cfg.tooltip);
-
-        this.cfg.rulerLayout.append(this.label);
+            if (this.cfg.tooltip){
+                this.label.attr('title', this.cfg.tooltip);
+            }
+            this.cfg.rulerLayout.append(this.label);
 
-        var height = this.cfg.viewer.height();
-        var x = 0;
-        this.painter.drawLine(x, 0, x, height);
-        x     = [-4, 4, 0];
-        var y = [0, 0, 4];
-        this.painter.fillPolygon(x, y);
-        this.painter.paint();
-        this.nodes = $J(this.painter.cnv).children();
+            var height = this.cfg.viewer.height();
+            var x = 0;
+            this.painter.drawLine(x, 0, x, height);
+            x     = [-4, 4, 0];
+            var y = [0, 0, 4];
+            this.painter.fillPolygon(x, y);
+            this.painter.paint();
+            this.nodes = $J(this.painter.cnv).children();
 
-        var style = {};
-        if (this.cfg.zIndex) {
-            style.zIndex = this.cfg.zIndex;
-            this.label.css(style);
-        }
-        style.backgroundColor = '';
+            var style = {};
+            if (this.cfg.zIndex) {
+                style.zIndex = this.cfg.zIndex;
+                this.label.css(style);
+            }
+            style.backgroundColor = '';
 
-        this.nodes.hide().css(style).addClass($N.cssPrefix + this.cfg.className)
+            this.nodes.hide().css(style).addClass($N.cssPrefix + this.cfg.className)
             .each(function(i, node) {
                 node.originalPosition = parseInt($J(node).css('left'));
             });
-    },
-
-    setText: function(text) {
-        if (this.label) {
-            text += '';
-            var labelWidth = this._textWidth(text, this.cfg.fontSize) + 10;
-            labelWidth += 'px';
-            if (this.label.css('width') != labelWidth) {
-                this.label.css({ width: labelWidth });
+        },
+
+        setText: function(text) {
+            if (this.label) {
+                text += '';
+                var labelWidth = this._textWidth(text, this.cfg.fontSize) + 10;
+                labelWidth += 'px';
+                if (this.label.css('width') != labelWidth) {
+                    this.label.css({
+                        width: labelWidth
+                    });
+                }
+                this.label.find('span').html(text);
             }
-            this.label.find('span').html(text);
-        }
-        return this;
-    },
-
-    move: function(pixelOffset) {
-        if (this.position != pixelOffset) {
-            if (pixelOffset < 0) {
-                pixelOffset = 0;
-            } else if (pixelOffset >= this.width) {
-                pixelOffset = this.width - 1;
+            return this;
+        },
+
+        move: function(pixelOffset) {
+            if (this.position != pixelOffset) {
+                if (pixelOffset < 0) {
+                    pixelOffset = 0;
+                } else if (pixelOffset >= this.width) {
+                    pixelOffset = this.width - 1;
+                }
+                this.nodes.each(function(i, node) {
+                    $J(node).css('left', Math.round(node.originalPosition + pixelOffset) + 'px');
+                });
+                var labelWidth = this.label.width();
+                var labelPixelOffset = pixelOffset - labelWidth / 2;
+                if (labelPixelOffset < 0)
+                    labelPixelOffset = 0;
+                else if (labelPixelOffset + labelWidth > this.width)
+                    labelPixelOffset = this.width - labelWidth;
+                this.label.css({
+                    left: Math.round(labelPixelOffset) + 'px'
+                });
+                this.position = pixelOffset;
             }
-            this.nodes.each(function(i, node) { 
-                $J(node).css('left', Math.round(node.originalPosition + pixelOffset) + 'px');
-            });
-            var labelWidth = this.label.width();
-            var labelPixelOffset = pixelOffset - labelWidth / 2;
-            if (labelPixelOffset < 0)
-                labelPixelOffset = 0;
-            else if (labelPixelOffset + labelWidth > this.width) 
-                labelPixelOffset = this.width - labelWidth;
-            this.label.css({left: Math.round(labelPixelOffset) + 'px'});            
-            this.position = pixelOffset;
-        }
-        return this;
-    },
-
-    show: function(offset) {
-        if (!this.visible) {
-            this.nodes.show();
-            this.label.show();
-            this.visible = true;
-        }
-        return this;
-    },
-
-    hide: function() {
-        this.nodes.hide();
-        this.label.hide();
-        this.visible = false;
-        return this;
-    },
-
-    isVisible: function() {
-        return this.visible;
-    },
-
-    blink: function(state) {
-        var speed = 200;
-        if (this.label && this.blinking != state) {
-            var span = this.label.find('span');
-
-            span.stop();
-
-            function fade(on) {
-                if (on) {
-                    span.animate({opacity: 1}, speed, null, 
-                        function() { fade(false) });
+            return this;
+        },
+
+        show: function(offset) {
+            if (!this.visible) {
+                this.nodes.show();
+                this.label.show();
+                this.visible = true;
+            }
+            return this;
+        },
+
+        hide: function() {
+            this.nodes.hide();
+            this.label.hide();
+            this.visible = false;
+            return this;
+        },
+
+        isVisible: function() {
+            return this.visible;
+        },
+
+        blink: function(state) {
+            var speed = 200;
+            if (this.label && this.blinking != state) {
+                var span = this.label.find('span');
+
+                span.stop();
+
+                function fade(on) {
+                    if (on) {
+                        span.animate({
+                            opacity: 1
+                        }, speed, null,
+                        function() {
+                            fade(false)
+                        });
+                    } else {
+                        span.animate({
+                            opacity: 0.4
+                        }, speed, null,
+                        function() {
+                            fade(true)
+                        })
+                    }
+                }
+
+                if (state) {
+                    fade();
                 } else {
-                    span.animate({opacity: 0.4}, speed, null, 
-                        function() { fade(true) })
+                    span.animate({
+                        opacity: 1
+                    }, speed);
                 }
-            }
 
-            if (state) {
-                fade();
-            } else {
-                span.animate({opacity: 1}, speed);
+                this.blinking = state;
             }
+            return this;
+        },
 
-            this.blinking = state;
-        }
-        return this;
-    },
-
-    _onMouseDown: function(evt) {
-        this.mouseDown = true;
-        this._onMouseMove(evt);
-        return false;
-    },
-
-    _onMouseMove: function(evt) {
-        if (this.mouseDown) {
-            var offset = (evt.pageX - this.cfg.rulerLayout.offset().left);
-            this.move(offset);
-            this.fire('move', {offset: this.position, finish: false});
+        _onMouseDown: function(evt) {
+            this.mouseDown = true;
+            this._onMouseMove(evt);
             return false;
-        }
-    },
+        },
 
-    _onMouseUp: function(evt) {
-        if (this.mouseDown) {
-            this.mouseDown = false;
-            this.fire('move', {id: this.id, offset: this.position, finish: true});
-            return false;
+        _onMouseMove: function(evt) {
+            if (this.mouseDown) {
+                var offset = (evt.pageX - this.cfg.rulerLayout.offset().left);
+                this.move(offset);
+                this.fire('move', { //calls move (see above)
+                    offset: this.position,
+                    finish: false
+                });
+                return false;
+            }
+        },
+
+        _onMouseUp: function(evt) {
+            if (this.mouseDown) {
+                this.mouseDown = false;
+                this.fire('move', {
+                    index: this.index,
+                    offset: this.position,
+                    finish: true
+                });
+                return false;
+            }
+        },
+
+        _observeMouseEvents: function() {
+            this.label.mousedown(this.attachWithEvent(this._onMouseDown))
+            .bind('click dragstart', function() {
+                return false;
+            });
+            this.cfg.rulerLayout.mousemove(this.attachWithEvent(this._onMouseMove));
+            this.cfg.rulerLayout.mouseup(this.attachWithEvent(this._onMouseUp));
+            $J(document).mouseup(this.attachWithEvent(this._onMouseUp));
         }
-    },
 
-    _observeMouseEvents: function() {
-        this.label.mousedown(this.attachWithEvent(this._onMouseDown))
-            .bind('click dragstart', function() {return false;});
-        this.cfg.rulerLayout.mousemove(this.attachWithEvent(this._onMouseMove));
-        this.cfg.rulerLayout.mouseup(this.attachWithEvent(this._onMouseUp));
-        $J(document).mouseup(this.attachWithEvent(this._onMouseUp));
-    }
+    //    _toString: function() {
+    //        return "<marker id="+id+" position="+position+" description=\""+
+    //            +description+"\"/>";
+    //    }
 
 
-});
+    });
 
-$N.notifyScriptLoad();
+    $N.notifyScriptLoad();
 
 });
index 543fb2e5cdfe7bcb78567d3b1deb61afc29f4e67..367f09ce0cfb65f0af654f07687926a159d86b6b 100644 (file)
 /**
  * TimeSide - Web Audio Components
  * Copyright (c) 2008-2009 Samalyse
- * Author: Olivier Guilyardi <olivier samalyse com>
+ * Author: Olivier Guilyardi <olivier samalyse com> and Riccardo Zaccarelli
  * License: GNU General Public License version 2.0
  */
 
 TimeSide(function($N, $J) {
 
-$N.Class.create("MarkerMap", $N.Core, {
-    markers: null,
-
-    initialize: function($super, markers) {
-        $super();
-        if (!markers)
-            markers = [];
-        this.markers = markers;
-    },
-
-    toArray: function() {
-        return [].concat(this.markers);
-    },
-
-    byIndex: function(index) {
-        return this.markers[index];
-    },
-
-    byId: function(id) {
-        var marker = null;
-        for (var i in this.markers) {
-            if (this.markers[i].id == id) {
-                marker = this.markers[i];
-                break;
+    $N.Class.create("MarkerMap", $N.Core, {
+        markers: null,
+        //the main div container:
+        divContainer: $J("#markers_div_id"),
+        initialize: function($super, markers) {
+            $super();
+            if (!markers){
+                markers = [];
             }
-        }
-        return marker;
-    },
-
-    indexOf: function(marker) {
-        var index = null;
-        for (var i in this.markers) {
-            if (this.markers[i].id == marker.id) {
-                index = parseInt(i);
-                break;
+            this.markers = markers;
+        },
+   
+        get: function(index){
+            return this.markers[index];
+
+        },
+
+
+        add: function(obj) {
+            var marker = this.createMarker(obj);
+            var idx = this.indexOf(marker);
+            
+            //adding the div
+            //marker.div = this.createDiv(marker,idx);
+            //setting focus and label description
+            //set label description
+            //this.setLabelDescription(marker);
+            //finally, set the focus to the text
+            //this.getHtmElm(marker,this.MHE_DESCRIPTION_TEXT).focus();
+
+
+            this.markers.splice(idx,0,marker);
+            //notifies controller.onMarkerMapAdd
+            this.fire('add', {
+                marker: marker,
+                index: idx
+            });
+            //this.fireRefreshLabels(idx+1,this.markers.length);
+            //this._reorder(marker.offset);
+            //this.fireEditMode(marker);
+            return idx;
+        },
+        //argument is either an object loaded from server or a number specifying the marker offset
+        createMarker: function(argument){
+            var marker = null;
+            if(typeof argument == 'object'){
+                var editable = CURRENT_USER_NAME === argument.author;
+                marker = {
+                    id: argument.public_id,
+                    offset: argument.time,
+                    desc: argument.description,
+                    title: argument.title,
+                    author: argument.author,
+                    isEditable: editable,
+                    isSaved: true
+
+                };
+            }else if(typeof argument == 'number'){
+                marker = {
+                    id: undefined, //before was: this.uniqid(),
+                    //now an undefined id means: not saved on server (see sendHTTP below)
+                    offset: parseFloat(argument),
+                    desc: "",
+                    title: "",
+                    author: CURRENT_USER_NAME,
+                    isEditable: true,
+                    isSaved: false
+                };
             }
-        }
-        return index;
-    },
+            return marker;
 
-    _reorder: function() {
-        this.markers.sort(this.compare);
-        for (var i in this.markers) {
-            this.fire('indexchange', {marker: this.markers[i], index: parseInt(i)});
-        }
-    },
-
-    add: function(offset, desc) {
-        var id = this.uniqid();
-        var marker = {id: id, offset: offset, desc: desc};
-        var i = this.markers.push(marker) - 1;
-        this.fire('add', {marker: marker, index: i});
-        this._reorder();
-        return marker;
-    },
-
-    remove: function(marker) {
-        if (marker) {
-            var i = this.indexOf(marker);
-            this.markers.splice(i, 1);
-            this.fire('remove', {marker: marker});
-            this._reorder();
-        }
-        return marker;
-    },
-
-    compare: function(marker1, marker2) {
-        if (marker1.offset > marker2.offset)
-            return 1;
-        if (marker1.offset < marker2.offset)
-            return -1;
-        return 0;
-    },
-
-    move: function(marker, offset) {
-        oldMarkers = [].concat(this.markers);
-        marker.offset = offset;
-        this._reorder();
-    },
-
-    getPrevious: function(offset, skip) {
-        var marker = null;
-        if (!skip) skip = 0;
-        markers = [].concat(this.markers).reverse();
-        $J(markers).each(function(i, m) {
-            if (offset > m.offset && !(skip--)) {
-                marker = m;
-                return false;
+        },
+
+        remove: function(index) {
+            var marker = this.get(index);
+            if (marker) {
+                if(marker.isSaved){
+                    this.removeHTTP(marker);
+                }
+                this.markers.splice(index, 1);
+                //notifies controller.js
+                this.fire('remove', {
+                    index: index
+                });
+            }
+            return marker;
+        },
+
+        move: function(markerIndex, newOffset){
+            var newIndex = this.indexOf(newOffset);
+            
+            //if we moved left to right, the insertion index is actually
+            //newIndex-1, as we must also consider to remove the current index markerIndex, so:
+            if(newIndex>markerIndex){
+                newIndex--;
+            }
+            //this way, we are sure that if markerIndex==newIndex we do not have to move,
+            //and we can safely first remove the marker then add it at the newIndex without
+            //checking if we moved left to right or right to left
+            var marker = this.markers[markerIndex];
+            marker.offset = newOffset;
+            marker.isSaved = marker.isEditable ? false : true;
+            if(newIndex != markerIndex){
+                this.markers.splice(markerIndex,1);
+                this.markers.splice(newIndex,0,marker);
             }
-        });
-        return marker;
-    },
-
-    getNext: function(offset, skip) {
-        var marker = null;
-        if (!skip) skip = 0;
-        $J(this.markers).each(function(i, m) {
-            if (offset < m.offset && !(skip--)) {
-                marker = m;
-                return false;
+            this.fire('moved', {
+                fromIndex: markerIndex,
+                toIndex: newIndex
+            });
+        },
+        //
+        //The core search index function: returns insertionIndex if object is found according to comparatorFunction,
+        //(-insertionIndex-1) if object is not found. This assures that if the returned
+        //number is >=0, the array contains the element, otherwise not and the element can be inserted at
+        //-insertionIndex-1
+        insertionIndex: function(object){
+            var offset;
+            if(typeof object == 'object'){
+                offset = object.offset;
+            }else if(typeof object == 'number'){
+                offset = object;
+            }else{ //to be sure...
+                offset = parseFloat(object);
             }
-        });
-        return marker;
-    },
+            var pInt = parseInt; //reference to parseInt (to increase algorithm performances)
+            var comparatorFunction = function(a,b){
+                return (a<b ? -1 : (a>b ? 1 : 0));
+            };
+            var data = this.markers;
+            var low = 0;
+            var high = data.length-1;
 
-    each: function(callback) {
-        $J(this.markers).each(callback);
-    }
-});
+            while (low <= high) {
+                //int mid = (low + high) >>> 1;
+                var mid = pInt((low + high)/2);
+                var midVal = data[mid];
+                var cmp = comparatorFunction(midVal.offset,offset);
+                if (cmp < 0){
+                    low = mid + 1;
+                }else if (cmp > 0){
+                    high = mid - 1;
+                }else{
+                    return mid; // key found
+                }
+            }
+            return -(low + 1);  // key not found
+        },
+        //indexOf is the same as insertionIndex, but returns a positive number.
+        //in other words, it is useful when we do not want to know if obj is already present
+        //in the map, but only WHERE WOULD be inserted obj in the map. obj can be a marker
+        //or an offset (time). In the latter case a dummy marker with that offset will be considered
+        indexOf: function(obj){
+            var idx = this.insertionIndex(obj);
+            return idx<0 ? -idx-1 : idx;
+        },
+        each: function(callback) {
+            $J(this.markers).each(callback);
+        },
+        //        length: function(){
+        //            return this.markers ? this.markers.length : 0;
+        //        },
+       
+
+        sendHTTP: function(marker, functionOnSuccess, showAlertOnError){
+
+            //itemid is the item (spund file) name
+            var sPath = window.location.pathname;
+            //remove last "/" or last "/#", if any...
+            sPath = sPath.replace(/\/#*$/,"");
+            var itemid = sPath.substring(sPath.lastIndexOf('/') + 1);
+
+            //WARNING: use single quotes for the whole string!!
+            //see http://stackoverflow.com/questions/4809157/i-need-to-pass-a-json-object-to-a-javascript-ajax-method-for-a-wcf-call-how-can
+            //            var data2send = '{"id":"jsonrpc", "params":[{"item_id":"'+ itemid+'", "public_id": "'+marker.id+'", "time": "'+
+            //            marker.offset+'","description": "'+marker.desc+'"}], "method":"telemeta.add_marker","jsonrpc":"1.0"}';
+           
+            var isSaved = marker.id !== undefined;
+            if(!isSaved){
+                marker.id=this.uniqid(); //defined in core;
+            }
+            var method = isSaved ? "telemeta.update_marker" : "telemeta.add_marker";
+            
+            var s = this.jsonify;
+            var data2send = '{"id":"jsonrpc", "params":[{"item_id":"'+ s(itemid)+
+            '", "public_id": "'+s(marker.id)+'", "time": "'+s(marker.offset)+
+            '", "author": "'+s(marker.author)+
+            '", "title": "'+s(marker.title)+
+            '","description": "'+s(marker.desc)+'"}], "method":"'+method+'","jsonrpc":"1.0"}';
+
+            $.ajax({
+                type: "POST",
+                url: '/json/',
+                contentType: "application/json",
+                data: data2send,
+                success: function(){
+                    if(!isSaved){
+                        marker.isSaved = true;
+                    }
+                    if(functionOnSuccess){
+                        functionOnSuccess();
+                    }
+                },
+                error: function(jqXHR, textStatus, errorThrown){
+                    if(showAlertOnError){
+                        var details = "\n(no further info available)";
+                        if(jqXHR) {
+                            details="\nThe server responded witha status of "+jqXHR.status+" ("+
+                                jqXHR.statusText+")\n\nDetails (request responseText):\n"+jqXHR.responseText;
+                        }
+                        alert("ERROR: Failed to save marker"+details);
+                    }
+                }
+            });
+
+            
+        },
+
+        jsonify: function(string){
+            var s = string;
+            if(typeof string == "string"){
+                s = string.replace(/\\/g,"\\\\")
+                .replace(/\n/g,"\\n")
+                .replace(/"/g,"\\\"");
+            }
+            return s;
+        },
+        removeHTTP: function(marker){
+
+            //  //itemid is the item (spund file) name
+            //  var sPath = window.location.pathname;
+            //  //remove last "/" or last "/#", if any...
+            //  sPath = sPath.replace(/\/#*$/,"");
+            //  var itemid = sPath.substring(sPath.lastIndexOf('/') + 1);
+            var public_id = marker.id;
+            //WARNING: use single quotes for the whole string!!
+            //see http://stackoverflow.com/questions/4809157/i-need-to-pass-a-json-object-to-a-javascript-ajax-method-for-a-wcf-call-how-can
+            var data2send = '{"id":"jsonrpc","params":["'+public_id+'"], "method":"telemeta.del_marker","jsonrpc":"1.0"}';
+            //            var map = this.cfg.map;
+            //            var me = this;
+            $.ajax({
+                type: "POST",
+                url: '/json/',
+                contentType: "application/json",
+                data: data2send,
+                dataType: "json"
+            
+            });
+            var g = 9;
+        }
+
+    });
 
-$N.notifyScriptLoad();
+    $N.notifyScriptLoad();
 
 });
index 04df2f62293ae0f220d364b5e536c6e65961f5a2..793b2a2d91a6989ed9be5e3a9ddb430c07b9d4dd 100644 (file)
 
 TimeSide(function($N, $J) {
 
-$N.Class.create("Player", $N.Core, {
-    skeleton: {
-        'div.viewer': {
-            'div.ruler': {}, 
-            'div.wave': {
-                'div.image-canvas': {},
-                'div.image-container': ['img.image']
-            }
+    $N.Class.create("Player", $N.Core, {
+        skeleton: {
+            'div.viewer': {
+                'div.ruler': {},
+                'div.wave': {
+                    'div.image-canvas': {},
+                    'div.image-container': ['img.image']
+                }
+            },
+            'div.control': {
+                'div.layout': {
+                    'div.playback': ['a.play', 'a.pause', 'a.rewind', 'a.forward', 'a.set-marker']
+                //,'input.textMarker']
+                }
+            }/*,
+        'div.marker-control': ['a.set-marker']*/
         },
-        'div.control': {
-            'div.layout': {
-                'div.playback': ['a.play', 'a.pause', 'a.rewind', 'a.forward', 'a.set-marker']
+        defaultContents: {
+            play: 'Play',
+            pause: 'Pause',
+            rewind: 'Rewind',
+            forward: 'Forward',
+            'set-marker': 'Set marker'
+        //,'text-marker' : 'textmarker'
+        },
+        elements: {},
+        ruler: null,
+        soundProvider: null,
+        map: null,
+        container: null,
+        imageWidth: null,
+        imageHeight: null,
+
+        initialize: function($super, container, cfg) {
+            $super();
+            if (!container)
+                throw new $N.RequiredArgumentError(this, 'container');
+            this.container = $J(container);
+            this.configure(cfg, {
+                image: null
+            });
+        },
+
+        free: function($super) {
+            this.elements = null;
+            this.container = null;
+            $super();
+        },
+
+        setSoundProvider: function(soundProvider) {
+            this.soundProvider = soundProvider;
+            return this;
+        },
+
+        setMarkerMap: function(map) {
+            this.map = map;
+            return this;
+        },
+
+        setImage: function(expr) {
+            this.cfg.image = expr;
+            this.refreshImage();
+        },
+
+        refreshImage: function() {
+            var src = null;
+            if (typeof this.cfg.image == 'function') {
+                src = this.cfg.image(this.imageWidth, this.imageHeight);
+            } else if (typeof this.cfg.image == 'string') {
+                src = this.cfg.image;
             }
-        }/*,
-        'div.marker-control': ['a.set-marker']*/
-    },
-    defaultContents: {
-        play: 'Play',
-        pause: 'Pause',
-        rewind: 'Rewind',
-        forward: 'Forward',
-        'set-marker': 'Set marker'
-    },
-    elements: {},
-    ruler: null,
-    soundProvider: null,
-    map: null,
-    container: null,
-    imageWidth: null,
-    imageHeight: null,
-
-    initialize: function($super, container, cfg) {
-        $super();
-        if (!container)
-            throw new $N.RequiredArgumentError(this, 'container');
-        this.container = $J(container);
-        this.configure(cfg, {
-            image: null
-        });
-    },
-
-    free: function($super) {
-        this.elements = null;
-        this.container = null;
-        $super();
-    },
-
-    setSoundProvider: function(soundProvider) {
-        this.soundProvider = soundProvider;
-        return this;
-    },
-
-    setMarkerMap: function(map) {
-        this.map = map;
-        return this;
-    },
-
-    setImage: function(expr) {
-        this.cfg.image = expr;
-        this.refreshImage();
-    },
-
-    refreshImage: function() {
-        var src = null;
-        if (typeof this.cfg.image == 'function') {
-            src = this.cfg.image(this.imageWidth, this.imageHeight);
-        } else if (typeof this.cfg.image == 'string') {
-            src = this.cfg.image;
-        }
 
-        if (src) 
-            this.elements.image.attr('src', src);
-    },
-
-    draw: function() {
-        this.debug('drawing');
-        $N.domReady(this.attach(this._setupInterface));
-        return this;
-    },
-
-    _setupInterface: function() {
-        this.elements = $N.Util.loadUI(this.container, this.skeleton, this.defaultContents);
-
-        // IE apparently doesn't send the second mousedown on double click:
-        var jump = $J.browser.msie ? 'mousedown dblclick' : 'mousedown';
-        this.elements.rewind.attr('href', '#').bind(jump, this.attach(this._onRewind))
-            .click(function() {return false; });
-        this.elements.forward.attr('href', '#').bind(jump, this.attach(this._onForward))
-            .click(function() {return false; });
-        this.elements.pause.attr('href', '#').bind('click', this.attach(this._onPause));
-        this.elements.play.attr('href', '#').bind('click', this.attach(this._onPlay));
-        this.elements.control.find('a').add(this.elements.setMarker)
+            if (src) {
+                this.elements.image.attr('src', src);
+            }
+        },
+
+        draw: function() {
+            this.debug('drawing');
+            $N.domReady(this.attach(this._setupInterface));
+            return this;
+        },
+
+        _setupInterface: function() {
+            this.elements = $N.Util.loadUI(this.container, this.skeleton, this.defaultContents);
+
+            // IE apparently doesn't send the second mousedown on double click:
+            var jump = $J.browser.msie ? 'mousedown dblclick' : 'mousedown';
+            this.elements.rewind.attr('href', '#').bind(jump, this.attach(this._onRewind))
+            .click(function() {
+                return false;
+            });
+            this.elements.forward.attr('href', '#').bind(jump, this.attach(this._onForward))
+            .click(function() {
+                return false;
+            });
+            this.elements.pause.attr('href', '#').bind('click', this.attach(this._onPause));
+            this.elements.play.attr('href', '#').bind('click', this.attach(this._onPlay));
+        
+            //assigning title string to all anchors???????
+            this.elements.control.find('a').add(this.elements.setMarker)
             .attr('href', '#')
             .each(function(i, a){
                 a = $J(a);
@@ -106,117 +115,158 @@ $N.Class.create("Player", $N.Core, {
                     a.attr('title', a.text());
             });
             
-        //this.elements.markerControl.find('a').attr('href', '#');
-        if (this.map) {
-            this.elements.setMarker.bind('click', this.attach(this._onSetMarker));
-        } else {
-            this.elements.setMarker.remove();
-        }
-        this.ruler = new $N.Ruler({
-            viewer: this.elements.viewer,
-            map: this.map,
-            soundProvider: this.soundProvider
-        });
-        this.ruler
+            //this.elements.markerControl.find('a').attr('href', '#');
+            if (this.map && CURRENT_USER_NAME) {
+                //configureMarkersDiv();
+                this.elements.setMarker.bind('click', this.attach(this._onSetMarker));
+            //this.elements.setMarker2.bind('click', this.attach(this._onSetMarker2));
+            //this.elements.textMarker.attr('type', 'text');
+            //this.elements.textMarker.bind('click', this.attach(this._onSetMarker2));
+          
+            } else {
+                this.elements.setMarker.remove();
+            }
+            //creating the ruler
+            this.ruler = new $N.Ruler({
+                viewer: this.elements.viewer,
+                //map: this.map,
+                soundProvider: this.soundProvider
+            });
+            //bind events to the ruler (see function observe in core.js, I guess,
+            //which overrides jQuery bind function):
+            //the first arg is basically the event name, the second
+            //arg is a function to execute each time the event is triggered
+            this.ruler
             .observe('markermove', this.forwardEvent)
             .observe('markeradd', this.forwardEvent)
             .observe('move', this.forwardEvent)
             .draw();
-        this.refreshImage();
-        this.resize();
-        var resizeTimer = null;
-        $J(window).resize(this.attach(function() {
-            if (resizeTimer)
-                clearTimeout(resizeTimer);
-            resizeTimer = setTimeout(this.attach(this.resize), 100);
-        }));
+            this.refreshImage();
+            this.resize();
+            var resizeTimer = null;
+            $J(window).resize(this.attach(function() {
+                if (resizeTimer)
+                    clearTimeout(resizeTimer);
+                resizeTimer = setTimeout(this.attach(this.resize), 100);
+            }));
         //this.container.resize(this.attach(this.resize)); // Can loop ?
-    },
-
-    resize: function(overrideHeight) {
-        this.debug("resizing");
-        var height;
-        if (overrideHeight === true) {
-            this.debug("override height");
-            height = this.elements.image.css('height', 'auto').height();
-        } else {
-            height = this.elements.wave.height();
-            this.debug("wave height:" + height);
-            if (!height) {
-                this.elements.image.one('load', this.attach(function() {
-                    this.resize(true);
-                    this.debug("image loaded");
-                }));
-                height = this.elements.image.height();
+        },
+
+        resize: function(overrideHeight) {
+            this.debug("resizing");
+            var height;
+            if (overrideHeight === true) {
+                this.debug("override height");
+                height = this.elements.image.css('height', 'auto').height();
+            } else {
+                height = this.elements.wave.height();
+                this.debug("wave height:" + height);
+                if (!height) {
+                    this.elements.image.one('load', this.attach(function() {
+                        this.resize(true);
+                        this.debug("image loaded");
+                    }));
+                    height = this.elements.image.height();
+                }
             }
-        }
 
-        var elements = this.elements.image
+            var elements = this.elements.image
             .add(this.elements.imageContainer)
             .add(this.elements.imageCanvas);
 
-        elements.css('width', 'auto'); // for IE6
+            elements.css('width', 'auto'); // for IE6
 
-        if (!height)
-            height = 200;
-        var style = {
-            width: this.elements.wave.width(),
-            height: height
-        }
-        elements.css(style);
-        this.imageWidth = style.width;
-        this.imageHeight = style.height;
-        this.refreshImage();
-        this.ruler.resize();
-        return this;
-    },
-
-    _onRewind: function() {
-        var offset = 0;
-        if (this.map) {
-            var position = this.soundProvider.getPosition();
-            var marker = this.map.getPrevious(position);
-            if (marker && this.soundProvider.isPlaying() 
-                && position - marker.offset < this.ruler.getUnitDuration())
-                marker = this.map.getPrevious(marker.offset)
-            if (marker) {
-                offset = marker.offset;
+            if (!height){
+                height = 200;
             }
-        }
-        this.fire('move', {offset: offset});
-        return false;
-    },
-
-    _onForward: function() {
-        var offset = this.soundProvider.getDuration();
-        if (this.map) {
-            var marker = this.map.getNext(this.soundProvider.getPosition());
-            if (marker) {
-                offset = marker.offset;
+            var style = {
+                width: this.elements.wave.width(),
+                height: height
             }
+            elements.css(style);
+            this.imageWidth = style.width;
+            this.imageHeight = style.height;
+            this.refreshImage();
+            this.ruler.resize();
+            return this;
+        },
+
+        _onRewind: function() {
+            var offset = 0;
+            if (this.map) {
+                var position = parseFloat(this.soundProvider.getPosition());
+                //            var marker = this.map.getPrevious(position);
+                //            if (marker && this.soundProvider.isPlaying()
+                //                && position - marker.offset < this.ruler.getUnitDuration())
+                //                marker = this.map.getPrevious(marker.offset)
+                //            if (marker) {
+                //                offset = marker.offset;
+                //            }
+                //
+                var idx = this.map.indexOf(position)-1;
+                if(idx>=0){
+                    var marker = this.map.get(idx);
+                    if(marker){
+                        offset = marker.offset;
+                    }
+                }
+            }
+            this.fire('move', {
+                offset: offset
+            });
+            return false;
+        },
+
+        _onForward: function() {
+            var offset = this.soundProvider.getDuration();
+            if (this.map) {
+                var position = parseFloat(this.soundProvider.getPosition());
+                var idx = this.map.insertionIndex(position);
+                if(idx>=0){ //the pointer is exactly on a marker, increase by one
+                    //otherwise the index is the marker itself and we wouldn't move ahead
+                    idx++;
+                }else{
+                    //we are not on a pointer, get the index of the marker
+                    //(see markermap insertionindex)
+                    idx = -idx-1;
+                }
+                if(idx>=0){
+                    var marker = this.map.get(idx);
+                    if(marker){
+                        offset = marker.offset;
+                    }
+                }
+            //            var marker = this.map.getNext(this.soundProvider.getPosition());
+            //            if (marker) {
+            //                offset = marker.offset;
+            //            }
+            }
+            this.fire('move', {
+                offset: offset
+            });
+            return false;
+        },
+
+        _onPlay: function() {
+            this.fire('play');
+            return false;
+        },
+
+        _onPause: function() {
+            this.fire('pause');
+            return false;
+        },
+
+        _onSetMarker: function() {
+            if (this.map) {
+                this.fire('markeradd', {
+                    offset: this.soundProvider.getPosition()
+                });
+            }
+            return false;
         }
-        this.fire('move', {offset: offset});
-        return false;
-    },
-
-    _onPlay: function() {
-        this.fire('play');
-        return false;
-    },
-
-    _onPause: function() {
-        this.fire('pause');
-        return false;
-    },
-
-    _onSetMarker: function() {
-        if (this.map) {
-            this.fire('markeradd', {offset: this.soundProvider.getPosition()});
-        }
-        return false;
-    }
-});
+    });
 
-$N.notifyScriptLoad();
+    $N.notifyScriptLoad();
 
 });
index 5932c431ef3791faca96ca1a118a1b505de0c4b0..e5697e4cff2c4819c0c3cdeba745b22b33992c06 100644 (file)
 
 TimeSide(function($N, $J) {
 
-$N.Class.create("Ruler", $N.Core, {
+    $N.Class.create("Ruler", $N.Core, {
 
-    fullSectionDuration: 60,
-    sectionSubDivision: 10,
-    sectionSteps: [[5, 1], [10, 1], [20, 2], [30, 5], [60, 10], [120, 20], [300, 30], 
+        fullSectionDuration: 60,
+        sectionSubDivision: 10,
+        sectionSteps: [[5, 1], [10, 1], [20, 2], [30, 5], [60, 10], [120, 20], [300, 30],
         [600, 60], [1800, 300], [3600, 600]],
-    sectionsNum: 0,
-    timeLabelWidth: 0,
-    pointerPos: 0,
-    layout: null,
-    width: null,
-    mouseDown: false,
-    pointer: null,
-    markers: new Array(),
-    duration: 0,
-    container: null,
-    waveContainer: null,
-
-    initialize: function($super, cfg) {
-        $super();
-        this.configure(cfg, {
-            viewer: [null, 'required'],
-            fontSize: 10,
-            map: null,
-            soundProvider: [null, 'required']
-        });
-        this.cfg.viewer = $J(this.cfg.viewer);
-        this.container = this.cfg.viewer.find('.' + $N.cssPrefix + 'ruler');
-        this.waveContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-canvas');
-        this._setDuration(this.cfg.soundProvider.getDuration());
-        var imgContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-container'); // for IE
-        this._observeMouseEvents(this.waveContainer.add(imgContainer));
-        if (this.cfg.map) {
-            this.cfg.map
-                .observe('add', this.attach(this._onMapAdd))
-                .observe('remove', this.attach(this._onMapRemove))
-                .observe('indexchange', this.attach(this._onMapIndexChange));
-        }
-        this.cfg.soundProvider.observe('update', this.attach(this._onSoundProviderUpdate));
-    },
-
-    free: function($super) {
-        this.layout = null;
-        this.container = null;
-        this.waveContainer = null;
-        this.cfg.viewer = null;
-        $super();
-    },
-
-    _computeLayout: function() {
-        this.width = this.waveContainer.width();
+        sectionsNum: 0,
+        timeLabelWidth: 0,
+        pointerPos: 0,
+        layout: null,
+        width: null,
+        mouseDown: false,
+        pointer: null,
+        markers: new Array(),
+        duration: 0,
+        container: null,
+        waveContainer: null,
+
+        initialize: function($super, cfg) {
+            $super();
+            this.configure(cfg, {
+                viewer: [null, 'required'],
+                fontSize: 10,
+                //map: null,
+                soundProvider: [null, 'required']
+            });
+            this.cfg.viewer = $J(this.cfg.viewer);
+            this.container = this.cfg.viewer.find('.' + $N.cssPrefix + 'ruler');
+            this.waveContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-canvas');
+            this._setDuration(this.cfg.soundProvider.getDuration());
+            var imgContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-container'); // for IE
+            
+            this._observeMouseEvents(this.waveContainer.add(imgContainer));
+            //if (this.cfg.map) {
+            //    this.cfg.map
+            //.observe('add', this.attach(this._onMapAdd))
+            //.observe('remove', this.attach(this._onMapRemove))
+            //.observe('indexchange', this.attach(this._onMapIndexChange));
+            //}
+            
+            this.cfg.soundProvider.observe('update', this.attach(this._onSoundProviderUpdate));
+        },
+
+        free: function($super) {
+            this.layout = null;
+            this.container = null;
+            this.waveContainer = null;
+            this.cfg.viewer = null;
+            $super();
+        },
+
+        _computeLayout: function() {
+            this.width = this.waveContainer.width();
                 
-        this.debug('container width: ' + this.width);
-        var i, ii = this.sectionSteps.length;
-        this.timeLabelWidth = this._textWidth('00:00', this.cfg.fontSize);
-        for (i = 0; i < ii; i++) {
-            var duration = this.sectionSteps[i][0];
-            var subDivision = this.sectionSteps[i][1];
-            var labelsNum = Math.floor(this.duration / duration);
-            if ((i == ii - 1) || (this.width / labelsNum > this.timeLabelWidth * 2)) {
-                this.fullSectionDuration = duration;
-                this.sectionSubDivision = subDivision;
-                this.sectionsNum = Math.floor(this.duration / this.fullSectionDuration);
-                break;
+            this.debug('container width: ' + this.width);
+            var i, ii = this.sectionSteps.length;
+            this.timeLabelWidth = this._textWidth('00:00', this.cfg.fontSize);
+            for (i = 0; i < ii; i++) {
+                var duration = this.sectionSteps[i][0];
+                var subDivision = this.sectionSteps[i][1];
+                var labelsNum = Math.floor(this.duration / duration);
+                if ((i == ii - 1) || (this.width / labelsNum > this.timeLabelWidth * 2)) {
+                    this.fullSectionDuration = duration;
+                    this.sectionSubDivision = subDivision;
+                    this.sectionsNum = Math.floor(this.duration / this.fullSectionDuration);
+                    break;
+                }
             }
-        }
-    },
+        },
 
-    getUnitDuration: function() {
-        return this.sectionSubDivision;
-    },
+        getUnitDuration: function() {
+            return this.sectionSubDivision;
+        },
 
-    resize: function() {
-        var pointerVisible = this.pointer && this.pointer.isVisible();
-        this._computeLayout();
-        this.draw();
-        if (pointerVisible) {
-            this.setPosition(this.cfg.soundProvider.getPosition());
-            this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying());
-            this.pointer.show();
-        }            
-    },
-
-    _setDuration: function(duration) {
-        this.duration = duration;
-        this._computeLayout();
-    },
-
-    setDuration: function(duration) {
-        if (duration == 0)
-            duration = 60;
-        if (this.duration != duration) {
-            this._setDuration(duration);
+        resize: function() {
+            var pointerVisible = this.pointer && this.pointer.isVisible();
+            this._computeLayout();
             this.draw();
-        }
-    },
+            if (pointerVisible) {
+                this.setPosition(this.cfg.soundProvider.getPosition());
+                this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying());
+                this.pointer.show();
+            }
+        },
+
+        _setDuration: function(duration) {
+            this.duration = duration;
+            this._computeLayout();
+        },
+
+        setDuration: function(duration) {
+            if (duration == 0)
+                duration = 60;
+            if (this.duration != duration) {
+                this._setDuration(duration);
+                this.draw();
+            }
+        },
 
-    _createSection: function(timeOffset, pixelWidth) {
-        var section = $J('<div/>')
+        _createSection: function(timeOffset, pixelWidth) {
+            var section = $J('<div/>')
             .addClass($N.cssPrefix + 'section')
             .css({
-                fontSize: this.cfg.fontSize + 'px', 
+                fontSize: this.cfg.fontSize + 'px',
                 fontFamily: 'monospace',
                 width: pixelWidth,
                 overflow: 'hidden'
             })
             .append($J('<div />').addClass($N.cssPrefix + 'canvas'));
 
-        var topDiv = $J('<div/>')
+            var topDiv = $J('<div/>')
             .addClass($N.cssPrefix + 'label')
             .appendTo(section);
-        var bottomDiv = $J('<div/>')
+            var bottomDiv = $J('<div/>')
             .addClass($N.cssPrefix + 'lines')
             .appendTo(section);
-        var empty = $J('<span/>').css({visibility: 'hidden'}).text('&nbsp;');
-        if (pixelWidth > this.timeLabelWidth) {
-            var text = $J('<span/>')
+            var empty = $J('<span/>').css({
+                visibility: 'hidden'
+            }).text('&nbsp;');
+            if (pixelWidth > this.timeLabelWidth) {
+                var text = $J('<span/>')
                 .text($N.Util.makeTimeLabel(timeOffset))
-                .bind('mousedown selectstart', function() {return false;});
-        } else {
-            var text = empty.clone();
-        }
-        topDiv.append(text);
-        bottomDiv.append(empty);
-        return section;
-    },
-
-    _drawSectionRuler: function(section, drawFirstMark) {
-        var j;
-        var jg = new jsGraphics(section.find('.' + $N.cssPrefix + 'canvas').get(0));
-        jg.setColor(this.layout.find('.' + $N.cssPrefix + 'lines').css('color'));
-        var height = section.height();
-        var ypos;
-        for (j = 0; j < section.duration; j += this.sectionSubDivision) {
-            if (j == 0) {
-                if (drawFirstMark) {
-                    ypos = 0;
+                .bind('mousedown selectstart', function() {
+                    return false;
+                });
+            } else {
+                var text = empty.clone();
+            }
+            topDiv.append(text);
+            bottomDiv.append(empty);
+            return section;
+        },
+
+        _drawSectionRuler: function(section, drawFirstMark) {
+            var j;
+            var jg = new jsGraphics(section.find('.' + $N.cssPrefix + 'canvas').get(0));
+            jg.setColor(this.layout.find('.' + $N.cssPrefix + 'lines').css('color'));
+            var height = section.height();
+            var ypos;
+            for (j = 0; j < section.duration; j += this.sectionSubDivision) {
+                if (j == 0) {
+                    if (drawFirstMark) {
+                        ypos = 0;
+                    } else {
+                        continue;
+                    }
                 } else {
-                    continue;
+                    ypos = (j == section.duration / 2) ? 1/2 + 1/8 : 3/4;
                 }
-            } else {
-                ypos = (j == section.duration / 2) ? 1/2 + 1/8 : 3/4;
+                var x = j / this.duration * this.width;
+                jg.drawLine(x, height * ypos, x, height - 1);
             }
-            var x = j / this.duration * this.width;
-            jg.drawLine(x, height * ypos, x, height - 1);
-        }
-        jg.paint();
-    },
+            jg.paint();
+        },
 
-    getHeight: function() {
-        return this.container.find('' + $N.cssPrefix + '.section').height();
-    },
+        getHeight: function() {
+            return this.container.find('' + $N.cssPrefix + '.section').height();
+        },
 
-    draw: function() {
-        if (!this.duration) {
-            this.debug("Can't draw ruler with a duration of 0");
-            return;
-        }
-        this.debug("draw ruler, duration: " + this.duration);
-        if (this.layout)
-            this.layout.remove();
-        this.layout = $J('<div/>')
+        draw: function() {
+            if (!this.duration) {
+                this.debug("Can't draw ruler with a duration of 0");
+                return;
+            }
+            this.debug("draw ruler, duration: " + this.duration);
+            if (this.layout){
+                this.layout.remove();
+            }
+            this.layout = $J('<div/>')
             .addClass($N.cssPrefix + 'layout')
-            .css({position: 'relative'}) // bugs on IE when resizing
+            .css({
+                position: 'relative'
+            }) // bugs on IE when resizing
             .bind('dblclick', this.attachWithEvent(this._onDoubleClick))
             //.bind('resize', this.attachWithEvent(this.resize)) // Can loop ?
             .appendTo(this.container);
 
-        //this.container.html(this.layout);
+            //this.container.html(this.layout);
 
-        var sections = new Array();
-        var currentWidth = 0;
-        var i;
-        for (i = 0; i <= this.sectionsNum; i++) {
-            if (i < this.sectionsNum) {
-                var duration = this.fullSectionDuration;
-                var width = Math.floor(duration / this.duration * this.width);
-            } else {
-                var duration = this.duration - i * this.fullSectionDuration;
-                var width = this.width - currentWidth;
+            var sections = new Array();
+            var currentWidth = 0;
+            var i;
+            for (i = 0; i <= this.sectionsNum; i++) {
+                if (i < this.sectionsNum) {
+                    var duration = this.fullSectionDuration;
+                    var width = Math.floor(duration / this.duration * this.width);
+                } else {
+                    var duration = this.duration - i * this.fullSectionDuration;
+                    var width = this.width - currentWidth;
 
-            }               
-            var section = this._createSection(i * this.fullSectionDuration, width);
-            if (i > 0) {
-                section.css({left: currentWidth, top: 0, position: 'absolute'});
+                }
+                var section = this._createSection(i * this.fullSectionDuration, width);
+                if (i > 0) {
+                    section.css({
+                        left: currentWidth,
+                        top: 0,
+                        position: 'absolute'
+                    });
+                }
+                section.duration = duration;
+                this.layout.append(section);
+                currentWidth += section.width();
+                sections[i] = section;
             }
-            section.duration = duration;
-            this.layout.append(section);
-            currentWidth += section.width();
-            sections[i] = section;
-        }
-
-        for (i = 0; i <= this.sectionsNum; i++) {
-            this._drawSectionRuler(sections[i], (i > 0));
-        }
 
-        this._createPointer();
-        this._drawMarkers();
-    },
+            for (i = 0; i <= this.sectionsNum; i++) {
+                this._drawSectionRuler(sections[i], (i > 0));
+            }
 
-    _createPointer: function() {
-        if (this.pointer) {
-            this.pointer.clear();
-        }
-        this.pointer = new $N.Marker({
-            rulerLayout: this.layout.get(0),
-            viewer: this.waveContainer,
-            fontSize: this.cfg.fontSize,
-            zIndex: 1000,
-            className: 'pointer',
-            tooltip: 'Move head'
-        });
-        this.pointer
+            this._createPointer();
+            //draw markers
+            if (this.cfg.map) {
+                $J(this.markers).each(function(i, m) {
+                    m.clear();
+                });
+                this.markers = new Array();
+                this.cfg.map.each(this.attach(function(i, m) {
+                    this.markers.push(this._drawMarker(m, i));
+                }));
+            }
+        //this._drawMarkers();
+        },
+
+        //        _drawMarkers: function() {
+        //            if (this.cfg.map) {
+        //                $J(this.markers).each(function(i, m) {
+        //                    m.clear();
+        //                });
+        //                this.markers = new Array();
+        //                this.cfg.map.each(this.attach(function(i, m) {
+        //                    this.markers.push(this._drawMarker(m, i));
+        //                }));
+        //            }
+        //        },
+
+        _createPointer: function() {
+            if (this.pointer) {
+                this.pointer.clear();
+            }
+            this.pointer = new $N.Marker({
+                rulerLayout: this.layout.get(0),
+                viewer: this.waveContainer,
+                fontSize: this.cfg.fontSize,
+                zIndex: 1000,
+                top:0,
+                className: 'pointer',
+                tooltip: 'Move head',
+                canMove: true
+            });
+            //            //create the label
+            //            var tsMainLabel = $.find('.' + $N.cssPrefix + 'label');
+            //            if(tsMainLabel){
+            //                var label = tsMainLabel.find('#' + $N.cssPrefix + 'pointerOffset');
+            //                if(!label){
+            //                    label = $("<span/>").id('#' + $N.cssPrefix + 'pointerOffset').css('zIndex','10').appendTo(tsMainLabel);
+            //                    this.pointer.label = label;
+            //                }
+            //            }
+
+            this.pointer
+            //.setText("+")
             .setText($N.Util.makeTimeLabel(0))
             .observe('move', this.attach(this._onPointerMove));
-    },
+        },
 
-    _drawMarkers: function() {
-        if (this.cfg.map) {
-            $J(this.markers).each(function(i, m) {m.clear();});
-            this.markers = new Array();
-            this.cfg.map.each(this.attach(function(i, m) {
-                this.markers.push(this._drawMarker(m, i));
-            }));
-        }
-    },
-
-    _movePointer: function(offset) {
-        if (offset < 0)
-            offset = 0;
-        else if (offset > this.duration)
-            offset = this.duration;
-            
-        pixelOffset = offset / this.duration * this.width;
-        if (this.pointer) {
-            this.pointer.move(pixelOffset);
-            this.pointer.setText($N.Util.makeTimeLabel(offset));
-        }            
-        this.pointerPos = offset;
-    },
+        _movePointer: function(offset) {
+            if (offset < 0){
+                offset = 0;
+            }else if (offset > this.duration){
+                offset = this.duration;
+            }
+            pixelOffset = offset / this.duration * this.width;
+            if (this.pointer) {
+                this.pointer.move(pixelOffset);
+                this.pointer.setText($N.Util.makeTimeLabel(offset));
+            }
+            this.pointerPos = offset;
+        },
 
-    _setPosition: function(offset) {
-        this._movePointer(offset);
-        if (this.pointer) {
-            this.pointer.show();
-        }            
-    },
+        _setPosition: function(offset) {
+            this._movePointer(offset);
+            if (this.pointer) {
+                this.pointer.show();
+            }
+        },
 
-    setPosition: function(offset) {
-        if (!this.mouseDown) {
-            this._setPosition(offset);
-        }
-    },
+        setPosition: function(offset) {
+            if (!this.mouseDown) {
+                this._setPosition(offset);
+            }
+        },
 
-    shiftPosition: function(delta) {
-        this.setPosition(this.pointerPos + delta);
-    },
+        shiftPosition: function(delta) {
+            this.setPosition(this.pointerPos + delta);
+        },
 
-    hidePointer: function() {
-        if (this.pointer)
-            this.pointer.hide();
-    },
+        hidePointer: function() {
+            if (this.pointer)
+                this.pointer.hide();
+        },
 
-    setBuffering: function(state) {
-        if (this.pointer) {
-            this.pointer.blink(state);
-        }
-    },
-/*
+        setBuffering: function(state) {
+            if (this.pointer) {
+                this.pointer.blink(state);
+            }
+        },
+        /*
     _onClick: function(evt) {
         var offset = (evt.pageX - this.container.offset().left) 
             / this.width * this.duration;
@@ -283,116 +321,162 @@ $N.Class.create("Ruler", $N.Core, {
         this.fire('move', {offset: offset});
     },
 */
-    _onMouseDown: function(evt) {
-        this.mouseDown = true;
-        this._onMouseMove(evt);
-        evt.preventDefault();
-    },
-
-    _onPointerMove: function(evt, data) {
-        this.mouseDown = true;
-        this._setPosition(data.offset / this.width * this.duration);
-        if(data.finish) {
-            this.fire('move', {offset: this.pointerPos});
-            this.mouseDown = false;
-        }
-        return false;
-    },
-
-    _onMouseMove: function(evt) {
-        if (this.mouseDown) {
-            var pixelOffset = evt.pageX - this.container.offset().left;
-            this._setPosition(pixelOffset / this.width * this.duration);
+        _onMouseDown: function(evt) {
+            this.mouseDown = true;
+            this._onMouseMove(evt);
+            evt.preventDefault();
+        },
+
+        _onPointerMove: function(evt, data) {
+            this.mouseDown = true;
+            this._setPosition(data.offset / this.width * this.duration);
+            if(data.finish) {
+                this.fire('move', {
+                    offset: this.pointerPos
+                });
+                this.mouseDown = false;
+            }
             return false;
-        }
-    },
+        },
 
-    _onMouseUp: function(evt) {
-        if (this.mouseDown) {
-            this.mouseDown = false;
-            this.fire('move', {offset: this.pointerPos});
-            return false;
-        }
-    },
+        _onMouseMove: function(evt) {
+            if (this.mouseDown) {
+                var pixelOffset = evt.pageX - this.container.offset().left;
+                this._setPosition(pixelOffset / this.width * this.duration);
+                return false;
+            }
+        },
+
+        _onMouseUp: function(evt) {
+            
+            if (this.mouseDown) {
+                this.mouseDown = false;
+                this.fire('move', {
+                    offset: this.pointerPos
+                });
+                return false;
+            }
+        },
 
-    _observeMouseEvents: function(element) {
-        element
-            .bind('click dragstart', function() {return false;})
+        _observeMouseEvents: function(element) {
+            if(!(CURRENT_USER_NAME)){
+                return;
+            }
+            element
+            .bind('click dragstart', function() {
+                return false;
+            })
             .bind('mousedown', this.attachWithEvent(this._onMouseDown))
             .bind('mousemove', this.attachWithEvent(this._onMouseMove))
             .bind('mouseup', this.attachWithEvent(this._onMouseUp));
-        $J(document)
+            $J(document)
             .bind('mousemove', this.attachWithEvent(this._onMouseMove));
-    },
+        },
 
-    _drawMarker: function(marker, index) {
-        if (marker.offset < 0)
-            marker.offset = 0;
-        else if (marker.offset > this.duration)
-            marker.offset = this.duration;
+        _drawMarker: function(marker, index) {
+            if (marker.offset < 0){
+                marker.offset = 0;
+            }else if (marker.offset > this.duration){
+                marker.offset = this.duration;
+            }
             
-        pixelOffset = marker.offset / this.duration * this.width;
-
-        m = new $N.Marker({
-            rulerLayout: this.layout.get(0),
-            viewer: this.waveContainer,
-            fontSize: this.cfg.fontSize,
-            className: 'marker',
-            id: marker.id,
-            tooltip: 'Move marker'
-        });
-        m.observe('move', this.attach(this._onMarkerMove))
-            .setText(index + 1)
+            pixelOffset = marker.offset / this.duration * this.width;
+
+            m = new $N.Marker({
+                rulerLayout: this.layout.get(0),
+                viewer: this.waveContainer,
+                fontSize: this.cfg.fontSize,
+                className: 'marker',
+                index: index,
+                tooltip: 'Move marker',
+                canMove: marker.isEditable
+            });
+            if(marker.isEditable){
+                m.observe('move', this.attach(this._onMarkerMove))
+            }
+            //m.observe('move', this.attach(this._onMarkerMove))
+            m
+            //.setText(index + 1)
             .move(pixelOffset)
             .show();
-        return m;
-    },
-
-    _onMarkerMove: function(e, data) {
-        if (data.finish) {
-            var offset = data.offset / this.width * this.duration;
-            this.fire('markermove', {id: data.id, offset: offset});
-        }
-    },
-
-    _onMapAdd: function(e, data) {
-        this.markers.push(this._drawMarker(data.marker, data.index));
-    },
-
-
-    _onMapRemove: function(e, data) {
-        $J(this.markers).each(this.attach(function(i, m) {
-            if (m.id == data.marker.id) {
-                m.clear();
-                this.markers.splice(i, 1);
+            return m;
+        },
+
+        _onMarkerMove: function(e, data) {
+            if (data.finish) {
+                var offset = data.offset / this.width * this.duration;
+                this.fire('markermove', {
+                    index: data.index,
+                    offset: offset
+                });
             }
-        }));
-    },
-
-    _onMapIndexChange: function(e, data) {
-        $J(this.markers).each(this.attach(function(i, m) {
-            if (m.id == data.marker.id) {
-                m.setText(data.index + 1);
-                return false;
+        },
+
+        add: function(marker, index){
+            this.markers.splice(index, 0, this._drawMarker(marker, index));
+        //this.markers.push(this._drawMarker(marker, index));
+        },
+
+        //        _onMapAdd2: function(e, data) {
+        //            this.markers.push(this._drawMarker(data.marker, data.index));
+        //        },
+
+        remove: function(index){
+            var rulermarker = this.markers[index];
+            rulermarker.clear();
+            this.markers.splice(index, 1);
+        },
+        
+        //it is assured that fromIndex!=toIndex and fromIndex!=toIndex+1 (see markermap.move)
+        move: function(fromIndex, toIndex){
+            var m = this.markers.splice(fromIndex,1)[0]; //remove
+            this.markers.splice(toIndex,0,m); //add
+        },
+
+        updateMarkerIndices:function(fromIndex, toIndex){
+            for(var i=fromIndex; i<=toIndex; i++){
+                this.markers[i].setIndex(i);
             }
-        }));
-    },
+        },
 
-    _onDoubleClick: function(evt) {
-        if (this.cfg.map) {
-            var offset = (evt.pageX - this.container.offset().left) 
+        _onDoubleClick: function(evt) {
+            if (CURRENT_USER_NAME) {
+                var offset = (evt.pageX - this.container.offset().left)
                 / this.width * this.duration;
-            this.fire('markeradd', {offset: offset});
-        }
-    },
+                this.fire('markeradd', {
+                    offset: offset
+                });
+            }
+        },
 
-    _onSoundProviderUpdate: function(e) {
-        this.setDuration(this.cfg.soundProvider.getDuration());
-        this.setPosition(this.cfg.soundProvider.getPosition());
-        this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying());
-    }
-});
+        _onSoundProviderUpdate: function(e) {
+            this.setDuration(this.cfg.soundProvider.getDuration());
+            this.setPosition(this.cfg.soundProvider.getPosition());
+            this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying());
+        }
+    });
 
-$N.notifyScriptLoad();
+    $N.notifyScriptLoad();
 
 });
+
+//        _onMapRemove: function(e, data) {
+        //            $J(this.markers).each(this.attach(function(i, m) {
+        //                if (m.id == data.marker.id) {
+        //                    m.clear();
+        //                    this.markers.splice(i, 1);
+        //                }
+        //            }));
+        //        },
+
+        //        onMapMove: function(fromIndex, toIndex) {
+        //            var min = Math.min(fromIndex, toIndex);
+        //            var max = Math.max(fromIndex, toIndex);
+        //            this.updateMarkerIndices(min,max);
+        ////            $J(this.markers).each(this.attach(function(i, m) {
+        ////                if (m.id == data.marker.id) {
+        ////                    m.setText(data.index + 1);
+        ////                    return false;
+        ////                }
+        ////            }));
+        //        },
index 95b0f517aaf96397d99695d0d4df4dc1e1e2c1a0..fe4cf976032b6cc4d4fb8792355d27d92578a43e 100644 (file)
  * License: GNU General Public License version 2.0
  */
 
-var TimeSide = function() { 
+//this global variable SEEMS to do a check on the variable jQuery, then
+//simply executes the argument (which is a function)
+var TimeSide = function() {
+    //arguments is an array-like object corresponding to the arguments passed to a function
     if (arguments[0]) {
         var toolkit = null;
-        if (typeof jQuery != 'undefined')
+        if (typeof jQuery != 'undefined'){
             toolkit = jQuery;
+        }
+        //call arguments[0] (a function) with arguments this and jQuery
         (arguments[0])(TimeSide, toolkit)
     }
 };
-
+//this is the first function instantiated. It SEEMS to check the document status and
+//load synchronously all the scripts
 TimeSide(function($N, $J) {
 
-$N.isDomLoaded = false;
-$N.isLoaded = false;
-$N.isLoading = false;
-$N.onLoadCallbacks = [];
-$N.cssPrefix = 'ts-';
-$N.debugging = false;
-
-$J(document).ready(function () {
-    $N.isDomLoaded = true;
-});
+    $N.isDomLoaded = false;
+    $N.isLoaded = false;
+    $N.isLoading = false;
+    $N.onLoadCallbacks = [];
+    $N.cssPrefix = 'ts-';
+    $N.debugging = false;
 
-$N.domReady = function(callback) {
-    // simply calling jQuery.ready() *after* the DOM is loaded doesn't work reliably,
-    // at least with jQuery 1.2.6
-    if ($N.isDomLoaded) 
-        callback();
-    else
-        $J(document).ready(callback);
-}
-
-$N.instances = [];
-$N.registerInstance = function(obj) {
-    $N.instances.push(obj);
-}
-
-$N.free = function() {
-    $J($N.instances).each(function(i, obj) {
-        obj.free();
+    $J(document).ready(function () {
+        $N.isDomLoaded = true;
     });
-}
 
-$J(window).unload($N.free);
+    $N.domReady = function(callback) {
+        // simply calling jQuery.ready() *after* the DOM is loaded doesn't work reliably,
+        // at least with jQuery 1.2.6
+        if ($N.isDomLoaded) {
+            callback();
+        } else{
+            $J(document).ready(callback);
+        }
+    }
 
-$N.loadScriptsNum = 0;
-$N.loadScriptsCallback = null;
-$N.loadScripts = function(root, scripts, callback) {
-    if ($N.loadScriptsCallback) {
-        throw "Timeside loader error: concurrent script loading";
+    $N.instances = [];
+    $N.registerInstance = function(obj) {
+        $N.instances.push(obj);
     }
 
-    $N.loadScriptsNum = scripts.length;
-    $N.loadScriptsCallback = callback;
+    $N.free = function() {
+        $J($N.instances).each(function(i, obj) {
+            obj.free();
+        });
+    }
+
+    $J(window).unload($N.free);
+
+    $N.loadScriptsNum = 0;
+    $N.loadScriptsCallback = null;
+    $N.loadScripts = function(root, scripts, callback) {
+        if ($N.loadScriptsCallback) {
+            throw "Timeside loader error: concurrent script loading";
+        }
+
+        $N.loadScriptsNum = scripts.length;
+        $N.loadScriptsCallback = callback;
 
-    var head= document.getElementsByTagName('head')[0];
-    for (i = 0; i < scripts.length; i++) {
+        var head= document.getElementsByTagName('head')[0];
+        for (i = 0; i < scripts.length; i++) {
 
-        var script = document.createElement('script');
-        script.type = 'text/javascript';
-        var debug = $N.debugging ? '?rand=' + Math.random() : '';
-        script.src = root + scripts[i] + debug;
-        head.appendChild(script);
+            var script = document.createElement('script');
+            script.type = 'text/javascript';
+            var debug = $N.debugging ? '?rand=' + Math.random() : '';
+            script.src = root + scripts[i] + debug;
+            head.appendChild(script);
+        }
     }
-}
 
-$N.notifyScriptLoad = function() {
-    if (--$N.loadScriptsNum == 0 && $N.loadScriptsCallback) {
-        var callback = $N.loadScriptsCallback;
-        $N.loadScriptsCallback = null;
-        callback();
+    $N.notifyScriptLoad = function() {
+        if (--$N.loadScriptsNum == 0 && $N.loadScriptsCallback) {
+            var callback = $N.loadScriptsCallback;
+            $N.loadScriptsCallback = null;
+            callback();
+        }
     }
-}
-
-$N.debug = function(state) {
-    $N.debugging = state;
-}
-
-$N.load = function(callback) {
-    $N.domReady(function() {
-        if ($N.isLoaded) {
-            if (callback) 
-                callback();
-        } else {
-            if (callback) 
-                $N.onLoadCallbacks.push(callback);
-
-            if (!$N.isLoading) {
-                $N.isLoading = true;
-                var re = /(.*)timeside.js/;
-                var root = '';
-                $J('head script').each(function(i, e) {
-                    if (match = re.exec(e.src)) {
-                        root = match[1];
-                    }
-                });
-
-                $N.loadScripts(root, ['core.js'], function() {
-                    $N.loadScripts(root, ['util.js'], function() {
-                        var scripts = ['controller.js', 'marker.js', 'markerlist.js', 
-                                       'markermap.js', 'player.js', 'ruler.js', 
-                                       'soundprovider.js'];
+
+    $N.debug = function(state) {
+        $N.debugging = state;
+    }
+
+    $N.load = function(callback) {
+        $N.domReady(function() {
+            if ($N.isLoaded) {
+                if (callback)
+                    callback();
+            } else {
+                if (callback)
+                    $N.onLoadCallbacks.push(callback);
+
+                if (!$N.isLoading) {
+                    $N.isLoading = true;
+                    var re = /(.*)timeside.js/;
+                    var root = '';
+                    $J('head script').each(function(i, e) {
+                        if ((match = re.exec(e.src))) {
+                            root = match[1];
+                        }
+                    });
+
+                    $N.loadScripts(root, ['core.js'], function() {
+                        $N.loadScripts(root, ['util.js'], function() {
+                            var scripts = ['controller.js', 'marker.js', 'markerlist.js',
+                            'markermap.js', 'player.js', 'ruler.js','divmarker.js',
+                            'soundprovider.js'];
                                                        
-                        $N.loadScripts(root, scripts, function() {
-                            $N.isLoaded = true;
-                            $N.isLoading = false;
-                            $J($N.onLoadCallbacks).each(function(i, callback) {
-                                callback();
+                            $N.loadScripts(root, scripts, function() {
+                                $N.isLoaded = true;
+                                $N.isLoading = false;
+                                $J($N.onLoadCallbacks).each(function(i, callback) {
+                                    callback();
+                                });
                             });
                         });
                     });
-                });
+                }
             }
-        }
-    });
-}
+        });
+    }
 
 });
index 94c42dc9a8a4f3a7bb4c414cc610474a7c6c89bc..2b7c800985d559fe8a01bfa8a397d13f213618a9 100755 (executable)
 
 TimeSide(function($N, $J) {
 
-$N.Util = {
-    _loadChild: function(container, tag, className, index, contents) {
-        var p = $N.cssPrefix;
-        var element = container.find('.' + p + className);
-        if (!element.length) {
-            element = $J(document.createElement(tag)).addClass(p + className);
-            if (contents[className]) {
-                element.text(contents[className]);
-            }
-            var children = container.children();
-            if (index < children.length) {
-                children.eq(index).before(element);
-            } else {
-                container.append(element);
+    $N.Util = {
+        _loadChild: function(container, tag, className, index, contents) {
+            var p = $N.cssPrefix;
+            var element = container.find('.' + p + className);
+            if (!element.length) {
+                element = $J(document.createElement(tag)).addClass(p + className);
+                if (contents[className]) {
+                    element.text(contents[className]);
+                }
+                var children = container.children();
+                if (index < children.length) {
+                    children.eq(index).before(element);
+                } else {
+                    container.append(element);
+                }
             }
-        }
-        return element;
-    },
-
-    _loadUI: function(container, skeleton, contents) {
-        var i = 0;
-        var elements = {};
-        with ($N.Util) {
-            if (skeleton[0]) {
-                $J(skeleton).each((function(i, selector) {
-                    var s = selector.split('.');
-                    elements[$N.Util.camelize(s[1])] = _loadChild(container, s[0], s[1], i++, contents);
-                }));
-            } else {
-                for (key in skeleton) {
-                    var s = key.split('.');
-                    var e = _loadChild(container, s[0], s[1], i++, contents);
-                    elements[$N.Util.camelize(s[1])] = e;
-                    $N.extend(elements, _loadUI(e, skeleton[key], contents));
+            return element;
+        },
+
+        _loadUI: function(container, skeleton, contents) {
+            var i = 0;
+            var elements = {};
+            with ($N.Util) {
+                if (skeleton[0]) {
+                    $J(skeleton).each((function(i, selector) {
+                        var s = selector.split('.');
+                        elements[$N.Util.camelize(s[1])] = _loadChild(container, s[0], s[1], i++, contents);
+                    }));
+                } else {
+                    for (key in skeleton) {
+                        var s = key.split('.');
+                        var e = _loadChild(container, s[0], s[1], i++, contents);
+                        elements[$N.Util.camelize(s[1])] = e;
+                        $N.extend(elements, _loadUI(e, skeleton[key], contents));
                     
+                    }
+                }
+                }
+            return elements;
+        },
+
+        loadUI: function(container, skeleton, contents) {
+            return $N.Util._loadUI($J(container), skeleton, contents);
+        },
+
+        makeTimeLabel: function(offset) {
+            var minutes = Math.floor(offset / 60);
+            if (minutes < 10)
+                minutes = '0' + minutes;
+            var seconds = Math.floor(offset % 60);
+            if (seconds < 10)
+                seconds = '0' + seconds;
+            return minutes + ':' + seconds;
+        },
+
+        camelize: function(str) {
+            var parts = str.split('-'), len = parts.length;
+            if (len == 1) return parts[0];
+
+            var camelized = str.charAt(0) == '-'
+            ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+            : parts[0];
+
+            for (var i = 1; i < len; i++)
+                camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+            return camelized;
+        },
+
+        setUpTabs:function(selIndex) {//called from within controller.js once all markers have been loaded.
+            //this is because we need all divs to be visible to calculate size. selIndex is optional, it defaults to 0
+            //
+            //declare variables:
+            var tabContainerHeight = '5ex'; //height for the tab container
+            var tabHeight = '3.5ex'; //height for the tab. Must be lower than tabContainerHeight
+            var tabPaddingTop ='.8ex'; //padding top of each tab. Increasing it will increase also the tab height, so
+            //compensate by decreasing tabHeight, in case. In any case, must be lower or equal to tabContainerHeight-tabHeight
+            var tabWidth = '10ex'; //width of each tab. Each tab from index 1 to n will be at left=n*tabWidth
+            var tabBottom ='-1px'; //bottom of each tab. Must be equal and opposite to the border of the div below the tab
+
+            //retrieve tab container:
+            var tabContainer = $("#tabs_container"); //change if tabContainer has to be retrieved diferently
+            //retrieve the tabs by checking the elements whose class name starts with "tab_"
+            //var tabs = $('a[class^="tab_"]'); //change if the tabs have to be determined differently.
+            var tabs = tabContainer.find('a[id^="tab_"]');
+            //function that retrieves the div relative to a tab (the div will be set visible.invisible according to tab click):
+            var tab2div = function(tab){
+                return $("#"+tab.attr("name"));
+            //ie, returns the element whose id is equal to the tab name.
+            //change here if div has to be determined differently
+            };
+            var selectedTabClassName = "tab_selected"; //change if needed
+            var unselectedTabClassName = "tab_unselected"; //change if needed
+            var tabClicked = function(index) {
+                for(var i=0; i<tabs.length; i++){
+                    var t = $(tabs[i]);
+                    if(i===index){
+                        t.removeClass(unselectedTabClassName).addClass(selectedTabClassName);
+                        tab2div(t).fadeIn('slow');
+                    }else{
+                        t.removeClass(selectedTabClassName).addClass(unselectedTabClassName);
+                        tab2div(t).hide();
+                    }
+                }
+                return false; //returning false avoids scroll of the anchor to the top of the page
+            //if the tab is an anchor, of course
+            };
+            //end of variables declaration
+
+            //tabContainer default css:
+            tabContainer.css({
+                'position':'relative',
+                'height':tabContainerHeight
+            });
+            //tabs default css:
+            tabs.css({
+                'position':'absolute',
+                'height':tabHeight,
+                'bottom':tabBottom,
+                'paddingTop':tabPaddingTop,
+                'width':tabWidth,
+                'color': '#000000',
+                'left':0, //this will be overridden for tabs from 1 to n (see below)
+                'textAlign':'center'
+            });
+            //setting the left property for all tabs from 1 to n
+            var left = parseFloat(tabWidth); //note that 40%, 33.3ex will be converted
+            //succesfully to 40 and 33.3 respectively
+            if(!isNaN(left)){
+                //retrieve the unit
+                var s = new String(left);
+                var unit = '';
+                if(s.length<tabWidth.length){
+                    unit = tabWidth.substring(s.length,tabWidth.length);
+                }
+                for(var i=1; i<tabs.length; i++){
+                    $(tabs[i]).css('left',(left*i)+unit);
                 }
             }
-        }
-        return elements;
-    },
-
-    loadUI: function(container, skeleton, contents) {
-        return $N.Util._loadUI($J(container), skeleton, contents);
-    },
-
-    makeTimeLabel: function(offset) {
-        var minutes = Math.floor(offset / 60);
-        if (minutes < 10)
-            minutes = '0' + minutes;
-        var seconds = Math.floor(offset % 60);
-        if (seconds < 10)
-            seconds = '0' + seconds;
-        return minutes + ':' + seconds;
-    },
-
-    camelize: function(str) {
-        var parts = str.split('-'), len = parts.length;
-        if (len == 1) return parts[0];
-
-        var camelized = str.charAt(0) == '-'
-          ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
-          : parts[0];
-
-        for (var i = 1; i < len; i++)
-          camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
-
-        return camelized;
-    }
 
-}
+            for (var i=0;i<tabs.length;i++){
+                // introduce a new scope (round brackets)
+                //otherwise i is retrieved from the current scope and will be always equal to tabs.length
+                //due to this loop
+                (function(tabIndex){
+                    $(tabs[i]).click(function(){
+                        return tabClicked(tabIndex);
+                    });
+                })(i);
+            }
+
+            this.setRoundBorder(tabs,'5px','5px',[0,1]);
+
+            if(!(selIndex)){
+                selIndex = 0;
+            }
+            $(tabs[selIndex]).trigger("click");
+        },
+
+        selectMarkerTab: function(){
+            $('#tab_markers').trigger("click");
+        },
+        //set cross browser round borders.
+        //elements: the html element or elements (jQuery syntax)
+        //hRadius the horizontal radius, or the horizontal vertical radius if the latter is omitted (see below)
+        //vRadius OPTIONAL the vertical radius. If missing, it defaults to hRadius
+        //angles: OTPIONAL. An array object of the corner indices where to apply radius. Indices are
+        //      considered clockwise starting from the top left corner,ie:
+        //      0=topleft, 1 topright, 2 bottomright, 3 bottomleft
+        //      If missing, it defaults to [0,1,2,3] (all indices)
+        setRoundBorder: function(elements, hRadius, vRadius, whichAngles){
+            if(!(vRadius)){
+                vRadius = hRadius;
+            }
+            var cssVal = hRadius+' '+vRadius;
+            if(!(whichAngles)){
+                whichAngles = [0,1,2,3];
+            }
+            $(elements).each(function(){
+                var element = $(this);
+                for(var i=0; i<whichAngles.length; i++){
+                    var keys=[];
+                    if(whichAngles[i]===0){
+                        keys=['-webkit-border-top-left-radius','moz-border-radius-topleft','border-top-left-radius'];
+                    }else if(whichAngles[i]===1){
+                        keys=['-webkit-border-top-right-radius','moz-border-radius-topright','border-top-right-radius'];
+                    }else if(whichAngles[i]===2){
+                        keys=['-webkit-border-bottom-right-radius','moz-border-radius-bottomright','border-bottom-right-radius'];
+                    }else if(whichAngles[i]===3){
+                        keys=['-webkit-border-bottom-left-radius','moz-border-radius-bottomleft','border-bottom-left-radius'];
+                    }
+                    if(keys){
+                        for(var j=0; j<keys.length; j++){
+                            element.css(keys[j],cssVal);
+                        }
+                    }
+                //            element.css('-webkit-border-top-left-radius',hRadius+' '+vRadius);
+                //            element.css('moz-border-radius-topleft',hRadius+' '+vRadius);
+                //            element.css('border-top-left-radius',hRadius+' '+vRadius);
+                }
+            });
+
+        },
+        
+
+    }
 
-$N.notifyScriptLoad();
+    $N.notifyScriptLoad();
 
 });