From e48195d69ac08974984c8bae85b7f41a77a67adf Mon Sep 17 00:00:00 2001
From: Jon Reid
Date: Mon, 4 Jun 2012 16:37:18 -0700
Subject: Timeline: Fixes to timeline to handle document switching & breadcrumb
 interactions under new DOM Architecture.

---
 .../Timeline/TimelinePanel.reel/TimelinePanel.js   | 3055 ++++++++++----------
 1 file changed, 1535 insertions(+), 1520 deletions(-)

(limited to 'js/panels/Timeline/TimelinePanel.reel')

diff --git a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js
index 6e9513f2..a5737334 100644
--- a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js
+++ b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js
@@ -1,1521 +1,1536 @@
-/* <copyright>
- This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
- No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
- (c) Copyright 2011 Motorola Mobility, Inc.  All Rights Reserved.
- </copyright> */
-
-var Montage = require("montage/core/core").Montage;
-var Component = require("montage/ui/component").Component;
-var nj = require("js/lib/NJUtils").NJUtils;
-
-var TimelinePanel = exports.TimelinePanel = Montage.create(Component, {
-
-    hasTemplate:{
-        value:true
-    },
-
-    /* === BEGIN: Models === */
-    _currentDocument: {
-        value : null
-    },
-
-    currentDocument : {
-        get : function() {
-            return this._currentDocument;
-        },
-        set : function(value) {
-            if (value === this._currentDocument) {
-                return;
-            }
-
-            if(!this._currentDocument && value.currentView === "design") {
-                this.enablePanel(true);
-            }
-
-            this._currentDocument = value;
-
-            if(!value) {
-                this.enablePanel(false);
-            } else if(this._currentDocument.currentView === "design") {
-                this._boolCacheArrays = false;
-                this.clearTimelinePanel();
-                this._boolCacheArrays = true;
-
-                // Rebind the document events for the new document context
-                this._bindDocumentEvents();
-
-                // TODO: Fix the init function so that it can be called here instead of when container changes
-                // this.initTimelineForDocument();
-            }
-        }
-    },
-
-    _arrLayers:{
-        value:[]
-    },
-
-    arrLayers:{
-        serializable:true,
-        get:function () {
-            return this._arrLayers;
-        },
-        set:function (newVal) {
-            this._arrLayers = newVal;
-            this.needsDraw = true;
-            this.cacheTimeline();
-        }
-    },
-
-    _temparrLayers:{
-        value:[]
-    },
-
-    temparrLayers:{
-        get:function () {
-            return this._temparrLayers;
-        },
-        set:function (newVal) {
-            this._temparrLayers = newVal;
-        }
-    },
-
-
-    _layerRepetition:{
-        value:null
-    },
-
-    layerRepetition:{
-        get:function () {
-            return this._layerRepetition;
-        },
-        set:function (newVal) {
-            this._layerRepetition = newVal;
-        }
-    },
-
-    // Set to false to skip array caching array sets in current document
-    _boolCacheArrays:{
-        value:true
-    },
-
-    _currentLayerNumber:{
-        value:0
-    },
-
-    currentLayerNumber:{
-        get:function () {
-            return this._currentLayerNumber;
-        },
-        set:function (newVal) {
-            if (newVal !== this._currentLayerNumber) {
-                this._currentLayerNumber = newVal;
-                this.cacheTimeline();
-            }
-        }
-    },
-
-    _currentLayerSelected:{
-        value: false
-    },
-    currentLayerSelected:{
-        get:function () {
-            return this._currentLayerSelected;
-        },
-        set:function (newVal) {
-            this._currentLayerSelected = newVal;
-            this.cacheTimeline();
-        }
-    },
-
-    _selectedLayerID:{
-        value:false
-    },
-    selectedLayerID:{
-        get:function () {
-            return this._selectedLayerID;
-        },
-        set:function (newVal) {
-            if (newVal === false) {
-                // We are clearing the timeline, so just set the value and return.
-                this._selectedLayerID = newVal;
-                return;
-            }
-            if (newVal !== this._selectedLayerID) {
-                var selectIndex = this.getLayerIndexByID(newVal);
-                this._selectedLayerID = newVal;
-                this._captureSelection = true;
-                if (this.currentLayerSelected !== false) {
-                	this.selectLayer(selectIndex, false);
-                }
-                if (this.currentLayersSelected !== false) {
-                	this.selectLayers(this.currentLayersSelected);
-                }
-                if ((this.currentLayersSelected === false) && (this.currentLayerSelected === false)) {
-                	this.selectLayers([]);
-                }
-                
-            }
-        }
-    },
-
-    _currentLayersSelected:{
-        value:[]
-    },
-    currentLayersSelected:{
-        get:function () {
-            return this._currentLayersSelected;
-        },
-        set:function (newVal) {
-            this._currentLayersSelected = newVal;
-            this.cacheTimeline();
-        }
-    },
-    
-    _currentSelectedContainer: {
-    	value: null
-    },
-    currentSelectedContainer: {
-    	get: function() {
-    		return this._currentSelectedContainer;
-    	},
-    	set: function(newVal) {
-            if(this._currentSelectedContainer !== newVal) {
-    		    this._currentSelectedContainer = newVal;
-
-                this._boolCacheArrays = false;
-                this.clearTimelinePanel();
-                this._boolCacheArrays = true;
-
-                // TODO: Fix the function so that we can remove this call here.
-                this.initTimelineForDocument();
-            }
-    	}
-    },
-
-    _millisecondsOffset:{
-        value:1000
-    },
-
-    millisecondsOffset:{
-        get:function () {
-            return this._millisecondsOffset;
-    },
-        set:function (newVal) {
-            if (newVal !== this._millisecondsOffset) {
-                this._millisecondsOffset= newVal;
-                this.drawTimeMarkers();
-                NJevent('tlZoomSlider',this);
-            }
-        }
-    },
-
-    _masterDuration:{
-        value:0
-    },
-
-    masterDuration:{
-        serializable:true,
-        get:function () {
-            return this._masterDuration;
-        },
-        set:function (val) {
-            this._masterDuration = val;
-            this.timebar.style.width = (this._masterDuration / 12) + "px";
-        }
-    },
-
-    _trackRepetition:{
-        value:null
-    },
-
-    trackRepetition:{
-        get:function () {
-            return this._trackRepetition;
-        },
-        set:function (newVal) {
-            this._trackRepetition = newVal;
-        }
-    },
-
-    _selectedKeyframes:{
-        value:[]
-    },
-
-    selectedKeyframes:{
-        serializable:true,
-        get:function () {
-            return this._selectedKeyframes;
-        },
-        set:function (newVal) {
-            this._selectedKeyframes = newVal;
-        }
-    },
-
-    _selectedTweens:{
-        value:[]
-    },
-
-    selectedTweens:{
-        serializable:true,
-        get:function () {
-            return this._selectedTweens;
-        },
-        set:function (newVal) {
-            this._selectedTweens = newVal;
-        }
-    },
-
-    _breadCrumbContainer:{
-            value:null
-    },
-
-    breadCrumbContainer:{
-        get:function () {
-            return this._breadCrumbContainer;
-        },
-        set:function (value) {
-            if (this._breadCrumbContainer !== value) {
-                this._breadCrumbContainer = value;
-            }
-        }
-    },
-
-    _isLayer:{
-        value:false
-    },
-
-    _firstTimeLoaded:{
-        value:true
-    },
-
-    _captureSelection:{
-        value:false
-    },
-
-    _openDoc:{
-        value:false
-    },
-
-    timeMarkerHolder:{
-        value:null
-    },
-    _dragAndDropHelper : {
-    	value: false
-    },
-    _dragAndDropHelperCoords: {
-    	value: false
-    },
-    _dragAndDropHelperOffset : {
-    	value: false
-    },
-    _dragLayerID : {
-    	value: null
-    },
-
-    layersDragged:{
-           value:[],
-           writable:true
-    },
-
-    dragLayerID : {
-    	get: function() {
-    		return this._dragLayerID;
-    	},
-    	set: function(newVal) {
-    		if (newVal !== this._dragLayerID) {
-    			this._dragLayerID = newVal;
-    		}
-    	}
-    },
-    _dropLayerID : {
-    	value: null
-    },
-    dropLayerID : {
-    	get: function() {
-    		return this._dropLayerID;
-    	},
-    	set: function(newVal) {
-    		if (newVal !== this._dropLayerID) {
-    			this._dropLayerID = newVal;
-    			
-    			var dragLayerIndex = this.getLayerIndexByID(this.dragLayerID),
-    				dropLayerIndex = this.getLayerIndexByID(this.dropLayerID),
-    				dragLayer = this.arrLayers[dragLayerIndex];
-                    this.layersDragged.push(dragLayer);
-                    this._layerDroppedInPlace = this.arrLayers[dropLayerIndex];
-
-    			this.arrLayers.splice(dragLayerIndex, 1);
-    			this.arrLayers.splice(dropLayerIndex, 0, dragLayer);
-    			this.cacheTimeline();
-    			
-    			// Clear for future DnD
-    			this._dropLayerID = null;
-    			this._dragLayerID = null;
-    			
-    			// Sometimes, just to be fun, the drop and dragend events don't fire.
-    			// So just in case, set the draw routine to delete the helper.
-    			this._deleteHelper = true;
-    			this.needsDraw = true;
-    		}
-    	}
-    },
-    _appendHelper: {
-    	value: false
-    },
-    _deleteHelper: {
-    	value: false
-    },
-    _scrollTracks: {
-    	value: false
-    },
-    useAbsolutePosition:{
-        value:true
-    },
-    /* === END: Models === */
-    /* === BEGIN: Draw cycle === */
-    prepareForDraw:{
-        value:function () {
-            this.initTimeline();
-
-            // Bind drag and drop event handlers
-            this.container_layers.addEventListener("dragstart", this.handleLayerDragStart.bind(this), false);
-            this.container_layers.addEventListener("dragend", this.handleLayerDragEnd.bind(this), false);
-            this.container_layers.addEventListener("dragover", this.handleLayerDragover.bind(this), false);
-            this.container_layers.addEventListener("drop", this.handleLayerDrop.bind(this), false);
-            
-            // Bind the handlers for the config menu
-            this.checkable_animated.addEventListener("click", this.handleAnimatedClick.bind(this), false);
-            this.checkable_relative.addEventListener("click", this.handleRelativeClick.bind(this), false);
-            this.checkable_absolute.addEventListener("click", this.handleAbsoluteClick.bind(this), false);
-            this.tl_configbutton.addEventListener("click", this.handleConfigButtonClick.bind(this), false);
-            document.addEventListener("click", this.handleDocumentClick.bind(this), false);
-
-        }
-    },
-
-    willDraw:{
-        value:function () {
-            if (this._isLayer) {
-                this._isLayer = false;
-            }
-        }
-    },
-    
-    draw: {
-    	value: function() {
-    		// Drag and Drop:
-    		// Do we have a helper to append?
-            if (this._appendHelper === true) {
-            	this.container_layers.appendChild(this._dragAndDropHelper);
-            	this._appendHelper = false;
-            }
-            // Do we need to move the helper?
-    		if (this._dragAndDropHelperCoords !== false) {
-    			if (this._dragAndDropHelper !== null) {
-    				this._dragAndDropHelper.style.top = this._dragAndDropHelperCoords;
-    			}
-    			this._dragAndDropHelperCoords = false;
-    		}
-    		// Do we need to scroll the tracks?
-    		if (this._scrollTracks !== false) {
-    			this.layout_tracks.scrollTop = this._scrollTracks;
-    			this._scrollTracks = false;
-    		}
-    		// Do we have a helper to delete?
-    		if (this._deleteHelper === true) {
-    			if (this._dragAndDropHelper === null) {
-    				// Problem....maybe a helper didn't get appended, or maybe it didn't get stored.
-    				// Try and recover the helper so we can delete it.
-    				var myHelper = this.container_layers.querySelector(".timeline-dnd-helper");
-    				if (myHelper != null) {
-    					this._dragAndDropHelper = myHelper;
-    				}
-    			}
-	            if (this._dragAndDropHelper !== null) {
-	            	// We need to delete the helper.  Can we delete it from container_layers?
-	            	if (this._dragAndDropHelper && this._dragAndDropHelper.parentNode === this.container_layers) {
-	            		this.container_layers.removeChild(this._dragAndDropHelper);
-	            		this._dragAndDropHelper = null;
-	            		this._deleteHelper = false;
-	            	}
-	            }
-                this.application.ninja.elementMediator.reArrangeDOM(this.layersDragged , this._layerDroppedInPlace);
-                this.layersDragged =[];
-    		}
-    	}
-    },
-    /* === END: Draw cycle === */
-    /* === BEGIN: Controllers === */
-    // Create an empty layer template object with minimal defaults and return it for use
-    createLayerTemplate:{
-        value:function () {
-            var returnObj = {};
-            
-            returnObj.layerData = {};
-            returnObj.layerData.layerName = null;
-            returnObj.layerData.layerID = null;
-            returnObj.layerData.isMainCollapsed = true;
-            returnObj.layerData.isPositionCollapsed = true;
-            returnObj.layerData.isTransformCollapsed = true;
-            returnObj.layerData.isStyleCollapsed = true;
-            returnObj.layerData.arrLayerStyles = [];
-            returnObj.layerData.arrLayerStyles = [];
-            returnObj.layerData.elementsList = [];
-            returnObj.layerData.deleted = false;
-            returnObj.layerData.isSelected = false;
-            returnObj.layerData.layerPosition = null;
-            returnObj.layerData.created = false;
-            returnObj.layerData.isTrackAnimated = false;
-            returnObj.layerData.currentKeyframeRule = null;
-            returnObj.layerData.trackPosition = 0;
-            returnObj.layerData.arrStyleTracks = [];
-            returnObj.layerData.tweens = [];
-            returnObj.layerData.layerTag = "";
-            returnObj.layerData.isVisible = true;
-            returnObj.layerData.docUUID = this.application.ninja.currentDocument._uuid;
-            returnObj.layerData.isTrackAnimated = false;
-            returnObj.layerData.triggerBinding = false;
-            returnObj.parentElementUUID = null;
-            returnObj.parentElement = null;
-            
-            return returnObj;
-        }
-    },
-    
-    // cache Timeline data in currentDocument.
-    cacheTimeline: {
-    	value: function() {
-			// Store the timeline data in currentDocument...
-			if (this._boolCacheArrays) {
-				// ... but only if we're supposed to.
-	    		this.application.ninja.currentDocument.tlArrLayers = this.arrLayers;
-	    		this.application.ninja.currentDocument.tlCurrentSelectedContainer = this.application.ninja.currentSelectedContainer;
-	    		this.application.ninja.currentDocument.tllayerNumber = this.currentLayerNumber;
-	    		this.application.ninja.currentDocument.tlCurrentLayerSelected = this.currentLayerSelected;
-	    		this.application.ninja.currentDocument.tlCurrentLayersSelected = this.currentLayersSelected;
-			}
-    	}
-    },
-    // Initialize Timeline cache in currentDocument.
-    initTimelineCache: {
-    	value: function() {
-			// Initialize the currentDocument for a new set of timeline data.
-			this.application.ninja.currentDocument.isTimelineInitialized = true;
-			this.application.ninja.currentDocument.tlArrLayers = [];
-    		this.application.ninja.currentDocument.tlCurrentSelectedContainer = this.application.ninja.currentSelectedContainer;
-    		this.application.ninja.currentDocument.tllayerNumber = this.currentLayerNumber;
-    		this.application.ninja.currentDocument.tlCurrentLayerSelected = false;
-    		this.application.ninja.currentDocument.tlCurrentLayersSelected = false;
-    	}
-    },
-    
-    // Create an array of style objects for an element, for use
-    // in creating a new layer
-    createLayerStyles : {
-    	value: function(ptrElement) {
-    		// TODO: Create logic to loop through 
-    		// CSS properties on element and build 
-    		// array of layer styles for return.
-    		// Right now this method just returns an array of one bogus style.
-    		
-    		var returnArray = [],
-    			newStyle = {}, 
-    			styleID = "1@0"; // format: layerID + "@" + style counter
-    			
-    		/* Example new style 	
-            newStyle.styleID = styleID;
-			newStyle.whichView = "propval";		// Which view do we want to show, usually property/value view (see Style)
-			newStyle.editorProperty = "top";	// the style property
-			newStyle.editorValue = 0;			// The current value
-			newStyle.ruleTweener = false; 
-			newStyle.isSelected = false;
-			
-			returnArray.push(newStyle);
-			*/
-			
-			return returnArray;
-    		
-    	}
-    },
-    
-    // Create an array of style track objects for an element, for use
-    // in creating a new layer
-    createStyleTracks : {
-    	value: function(ptrElement) {
-    		// TODO: Create logic to loop through 
-    		// CSS properties on element and build 
-    		// array of layer styles for return.
-    		// Right now this method just returns an array of one bogus style.
-    		
-    		var returnArray = [];
-						
-			return returnArray;
-    		
-    	}
-    },
-
-    // Bind all document-specific events (pass in true to unbind)
-    _bindDocumentEvents : {
-        value: function(boolUnbind) {
-            var arrEvents = ["deleteLayerClick",
-                             "newLayer",
-                             "deleteLayer",
-                             "elementAdded",
-                             "elementsRemoved",
-                             "elementReplaced",
-                             "selectionChange"],
-                i,
-                arrEventsLength = arrEvents.length;
-
-            if (boolUnbind) {
-                for (i = 0; i < arrEventsLength; i++) {
-                    this.eventManager.removeEventListener(arrEvents[i], this, false);
-                }
-            } else {
-                for (i = 0; i < arrEventsLength; i++) {
-                    this.eventManager.addEventListener(arrEvents[i], this, false);
-                }
-            }
-        }
-    },
-
-    // Initialize the timeline, runs only once when the timeline component is first loaded
-    initTimeline:{
-        value:function () {
-        	
-        	// Get some selectors
-            this.layout_tracks = this.element.querySelector(".layout-tracks");
-            this.layout_markers = this.element.querySelector(".layout_markers");
-            
-            // Add some event handlers
-            this.timeline_leftpane.addEventListener("mousedown", this.timelineLeftPaneMousedown.bind(this), false);
-            this.timeline_leftpane.addEventListener("mouseup", this.timelineLeftPaneMouseup.bind(this), false);
-            this.layout_tracks.addEventListener("scroll", this.updateLayerScroll.bind(this), false);
-            this.user_layers.addEventListener("scroll", this.updateLayerScroll.bind(this), false);
-            this.end_hottext.addEventListener("changing", this.updateTrackContainerWidth.bind(this), false);
-            this.playhead.addEventListener("mousedown", this.startPlayheadTracking.bind(this), false);
-            this.playhead.addEventListener("mouseup", this.stopPlayheadTracking.bind(this), false);
-            this.time_markers.addEventListener("click", this.updatePlayhead.bind(this), false);
-            
-            // Bind some bindings
-            Object.defineBinding(this, "currentSelectedContainer", {
-                boundObject:this.application.ninja,
-                boundObjectPropertyPath:"currentSelectedContainer",
-                oneway:true
-            });
-            
-			// Start the panel out in disabled mode by default
-			// (Will be switched on later, if appropriate).
-            this.enablePanel(false);
-
-        }
-    },
-
-    // Initialize the timeline for a document.
-    // Called when a document is opened (new or existing), or when documents are switched.
-    initTimelineForDocument:{
-        value:function () {
-
-
-            var myIndex,
-            	boolAlreadyInitialized = false;
-            this.drawTimeMarkers();
-            // Document switching
-            // Check to see if we have saved timeline information in the currentDocument.
-            if ((typeof(this.application.ninja.currentDocument.isTimelineInitialized) === "undefined")) {
-            	//console.log('TimelinePanel.initTimelineForDocument: new Document');
-                // No, we have no information stored.
-                // This could mean we are creating a new file, OR are opening an existing file.
-                
-                // First, initialize the caches.
-				this.initTimelineCache();
-                this.temparrLayers = [];
-
-				// That's all we need to do for a brand new file. 
-                // But what if we're opening an existing document?
-                if (!this.application.ninja.documentController.creatingNewFile && this.application.ninja.currentDocument.currentView !== "code") {
-                    // Opening an existing document. If it has DOM elements we need to restore their timeline info
-                    if (this.application.ninja.currentDocument.model.documentRoot.children[0]) {
-                        // Yes, it has DOM elements. Loop through them and create a new object for each.
-                        for (myIndex = 0; this.application.ninja.currentDocument.model.documentRoot.children[myIndex]; myIndex++) {
-                            this._openDoc = true;
-                            this.restoreLayer(this.application.ninja.currentDocument.model.documentRoot.children[myIndex]);
-                        }
-                    }
-                }
-                
-                // Draw the repetition.
-                this.arrLayers = this.temparrLayers;
-                this.currentLayerNumber = this.arrLayers.length;
-                boolAlreadyInitialized = true;
-                
-			} else if (this.application.ninja.currentDocument.setLevel) {
-            	//console.log('TimelinePanel.initTimelineForDocument: breadCrumbClick');
-				// Information stored, but we're moving up or down in the breadcrumb.
-				// Get the current selection and restore timeline info for its children.
-                var parentNode = this.application.ninja.currentSelectedContainer,
-                	storedCurrentLayerNumber = this.application.ninja.currentDocument.tllayerNumber;
-                this.temparrLayers = [];
-                
-                for (myIndex = 0; parentNode.children[myIndex]; myIndex++) {
-                    this._openDoc = true;
-                    this.restoreLayer(parentNode.children[myIndex]);
-
-                }
-                // Draw the repetition.
-                this.arrLayers = this.temparrLayers;
-                this.currentLayerNumber = storedCurrentLayerNumber;
-                boolAlreadyInitialized = true;
-                this.application.ninja.currentDocument.setLevel = false;
-
-
-            } else {
-            	//console.log('TimelinePanel.initTimelineForDocument: else fallback');
-                // we do have information stored.  Use it.
-                var i = 0, 
-                	tlArrLayersLength = this.application.ninja.currentDocument.tlArrLayers.length;
-                
-                // We're reading from the cache, not writing to it.
-            	this._boolCacheArrays = false;
-                for (i = 0; i < tlArrLayersLength; i++) {
-                    if (this.application.ninja.currentDocument.tlArrLayers[i].layerData.isSelected === true) {
-                        this.application.ninja.currentDocument.tlArrLayers[i].layerData._isFirstDraw = true;
-                    } else {
-                    	this.application.ninja.currentDocument.tlArrLayers[i].layerData._isFirstDraw = false;
-                    }
-                }
-                this.arrLayers = this.application.ninja.currentDocument.tlArrLayers;
-                this.currentLayerNumber = this.application.ninja.currentDocument.tllayerNumber;
-                this.currentLayerSelected = this.application.ninja.currentDocument.tlCurrentLayerSelected;
-                this.currentLayersSelected = this.application.ninja.currentDocument.tlCurrentLayersSelected;
-
-
-                //debugger;
-                if (typeof(this.application.ninja.currentDocument.tlCurrentSelectedContainer) !== "undefined") {
-//                	this.application.ninja.currentSelectedContainer=this.application.ninja.currentDocument.tlCurrentSelectedContainer;
-                }
-                
-                // Are we only showing animated layers?
-				if (this.application.ninja.currentDocument.boolShowOnlyAnimated) {
-					// Fake a click.
-					var evt = document.createEvent("MouseEvents");
-					evt.initMouseEvent("click");
-					this.checkable_animated.dispatchEvent(evt);
-				}
-
-				// Ok, done reading from the cache.
-				this._boolCacheArrays = true;
-				
-				// Reset master duration
-				this.resetMasterDuration();
-            }
-        }
-    },
-
-    // Clear the currently-displayed document (and its events) from the timeline.
-    clearTimelinePanel:{
-        value:function () {
-            // Remove events
-            this._bindDocumentEvents(true);
-
-            // Remove every event listener for every selected tween in the timeline
-            this.deselectTweens();
-
-            // Reset visual appearance
-            // Todo: Maybe this should be stored per document, so we can persist between document switch?
-            this.application.ninja.timeline.playhead.style.left = "-2px";
-            this.application.ninja.timeline.playheadmarker.style.left = "0px";
-            this.application.ninja.timeline.updateTimeText(0.00);
-            this.timebar.style.width = "0px";
-			this.checkable_animated.classList.remove("checked");
-            this.currentLayerNumber = 0;
-            this.currentLayerSelected = false;
-            this.currentLayersSelected = false;
-            this.selectedKeyframes = [];
-            this.selectedTweens = [];
-            this._captureSelection = false;
-            this._openDoc = false;
-            this.end_hottext.value = 25;
-            this.updateTrackContainerWidth();
-            this.masterDuration = 0;
-            // Clear the repetitions
-            if (this.arrLayers.length > 0) {
-                this.arrLayers = [];
-                this.arrLayers.length = 0;
-            }
-        }
-    },
-
-    handleDocumentChange:{
-        value:function () {
-
-        }
-    },
-
-    updateTrackContainerWidth:{
-        value:function () {
-            this.container_tracks.style.width = (this.end_hottext.value * 80) + "px";
-            this.master_track.style.width = (this.end_hottext.value * 80) + "px";
-            this.time_markers.style.width = (this.end_hottext.value * 80) + "px";
-            if (this.timeMarkerHolder) {
-                this.time_markers.removeChild(this.timeMarkerHolder);
-            }
-            this.drawTimeMarkers();
-        }
-    },
-
-    updateLayerScroll:{
-        value:function () {
-            this.user_layers.scrollTop = this.layout_tracks.scrollTop;
-            this.layout_markers.scrollLeft = this.layout_tracks.scrollLeft;
-         	this.playheadmarker.style.top = this.layout_tracks.scrollTop + "px";
-        }
-    },
-
-    startPlayheadTracking:{
-        value:function () {
-            this.time_markers.onmousemove = this.updatePlayhead.bind(this);
-        }
-    },
-
-    stopPlayheadTracking:{
-        value:function () {
-            this.time_markers.onmousemove = null;
-        }
-    },
-
-    updatePlayhead:{
-        value:function (event) {
-            var clickedPosition = event.target.offsetLeft + event.offsetX;
-            this.playhead.style.left = (clickedPosition - 2) + "px";
-            this.playheadmarker.style.left = clickedPosition + "px";
-            var currentMillisecPerPixel = Math.floor(this.millisecondsOffset / 80);
-            var currentMillisec = currentMillisecPerPixel * clickedPosition;
-            this.updateTimeText(currentMillisec);
-        }
-    },
-
-    handleSelectionChange:{
-        value:function () {
-            var layerIndex, 
-            	i = 0,
-            	j = 0,
-            	arrLayersLength = this.arrLayers.length,
-            	intNumSelected = this.application.ninja.selectedElements.length,
-            	checkIndex = 0;
-            	
-            this.deselectTweens();
-            //console.log("TimelinePanel.handleSelectionChange")
-            if (intNumSelected === 0) {
-            	this.selectLayers([]);
-            	this.currentLayerSelected = false;
-            	this.currentLayersSelected = false;
-            }
-            
-            if (intNumSelected === 1) {
-            	this.currentLayersSelected = false;
-                if (this.application.ninja.selectedElements[0]) {
-                	checkIndex = this.application.ninja.selectedElements[0].uuid;
-                    for (i = 0; i < arrLayersLength; i++) {
-                    	var currIndex = this.arrLayers[i].layerData.elementsList[0].uuid,
-                    		layerID = this.arrLayers[i].layerData.layerID,
-                    		layerIndex = 0;
-                        if (checkIndex === currIndex) {
-                            layerIndex = this.getLayerIndexByID(layerID);
-                            this._captureSelection = false;
-                            this.selectLayer(layerIndex);
-                            this._captureSelection = true;
-                        }
-                    }
-                }
-            }
-            
-            if (intNumSelected > 1) {
-            	// Build an array of indexes of selected layers to give to the selectLayers method
-            	var arrSelectedIndexes = [];
-            	this.currentLayerSelected = false;
-            	for (i = 0; i < intNumSelected; i++) {
-            		var currentCheck = this.application.ninja.selectedElements[i].uuid;
-            		//console.log("checking ", currentCheck);
-            		for (j = 0; j < arrLayersLength; j++) {
-            			//console.log(".......... ", this.arrLayers[j].layerData.elementsList[0].uuid)
-            			if (currentCheck === this.arrLayers[j].layerData.elementsList[0].uuid) {
-            				//console.log("...............Yes!")
-            				arrSelectedIndexes.push(j);
-            			}
-            		}
-            	}
-            	this.selectLayers(arrSelectedIndexes);
-            }
-        }
-    },
-
-
-
-    selectLayers:{
-        value:function (arrSelectedIndexes) {
-
-            var i = 0,
-            	arrLayersLength = this.arrLayers.length,
-            	arrSelectedIndexesLength = arrSelectedIndexes.length,
-            	userSelection = false;
-            
-            //console.log(arrSelectedIndexes);
-            
-
-            if (this.selectedKeyframes) {
-                this.deselectTweens();
-            }
-            
-            for (i = 0; i < arrLayersLength; i++) {
-            	this.arrLayers[i].layerData.isSelected = false;
-            	this.triggerLayerBinding(i);
-            }
-            
-            this.currentLayersSelected = false;
-            if (arrSelectedIndexesLength > 0) {
-            	this.currentLayersSelected = [];
-            }
-            
-            
-            for (i = 0; i < arrLayersLength; i++) {
-            	if (arrSelectedIndexes.indexOf(i) > -1) {
-            		this.arrLayers[i].layerData.isSelected = true;
-            		this.arrLayers[i].isSelected = true;
-            		this.triggerLayerBinding(i);
-            		this.currentLayersSelected.push(i);
-            	}
-            }
-
-            this.layerRepetition.selectedIndexes = arrSelectedIndexes;
-
-			// TODO: Set up for user selection.
-            if (userSelection) {
-                if (this._captureSelection) {
-
-                    if (this.currentLayerSelected.layerData.elementsList.length >= 1) {
-                        this.application.ninja.selectionController.selectElements(this.currentLayerSelected.layerData.elementsList);
-                    } else {
-                        this.application.ninja.selectionController.executeSelectElement();
-                    }
-
-                }
-                this._captureSelection = true;
-            }
-            
-            // Finally, reset the master duration.
-            this.resetMasterDuration();
-        }
-    },
-
-    deselectTweens:{
-        value:function () {
-            for (var i = 0; i < this.selectedTweens.length; i++) {
-                this.selectedTweens[i].deselectTween();
-            }
-            this.selectedTweens = null;
-            this.selectedTweens = new Array();
-        }
-    },
-
-    timelineLeftPaneMousedown:{
-        value:function (event) {
-            var ptrParent = nj.queryParentSelector(event.target, ".container-layer");
-            if (ptrParent !== false) {
-                var myIndex = this.getActiveLayerIndex();
-                if (myIndex !== false) {
-                	this.selectLayer(myIndex, true);
-                }
-                
-            }
-            this._isMousedown = true;
-        }
-    },
-
-    timelineLeftPaneMouseup:{
-        value:function (event) {
-			this._isMousedown = false;
-        }
-    },
-
-    createNewLayer:{
-        value:function (object) {
-            var newLayerName = "",
-                thingToPush = this.createLayerTemplate(),
-                myIndex = 0,
-                i = 0,
-                arrLayersLength = this.arrLayers.length;
-
-			// Make up a layer name.
-            this.currentLayerNumber = this.currentLayerNumber + 1;
-            newLayerName = "Layer " + this.currentLayerNumber;
-
-			// Possibly currentLayerNumber doesn't correctly reflect the
-			// number of layers.  Check that.
-            // Commented out to fix WebGL rendering bug
-            /*for(k = 0; k < arrLayersLength; k++){
-                if(this.arrLayers[k].layerData.layerName === newLayerName){
-                     this.currentLayerNumber = this.currentLayerNumber + 1;
-                     newLayerName = "Layer " + this.currentLayerNumber;
-                     break;
-                }
-            }*/
-            // We will no longer have multiple things selected, so wipe that info out
-            // if it isn't already gone.
-            this.currentLayersSelected = false;
-            
-            // thingToPush is the template we just got.  Now fill it in.
-            thingToPush.layerData.layerName = newLayerName;
-            thingToPush.layerData.layerTag = "<" + object.nodeName.toLowerCase() + ">";
-            thingToPush.layerData.layerID = this.currentLayerNumber;
-            thingToPush.parentElement = this.application.ninja.currentSelectedContainer;
-            thingToPush.layerData.isSelected = true;
-            thingToPush.layerData._isFirstDraw = true;
-            thingToPush.layerData.created = true;
-            
-            if (this.checkable_animated.classList.contains("checked")) {
-            	thingToPush.layerData.isVisible = false;
-            }
-			
-            if (this.layerRepetition.selectedIndexes) {
-                // There is a selected layer, so we need to splice the new layer on top of it.
-                myIndex = this.layerRepetition.selectedIndexes[0];
-                if (typeof(myIndex) === "undefined") {
-                	// Edge case: sometimes there's nothing selected, so this will be "undefined"
-                	// In that case, set it to 0, the first layer.
-                	myIndex = 0;
-                }
-                for (var i = 0; i < this.layerRepetition.selectedIndexes.length; i++) {
-                	if (myIndex > this.layerRepetition.selectedIndexes[i]) {
-                		myIndex = this.layerRepetition.selectedIndexes[i];
-                	}
-                }
-                thingToPush.layerData.layerPosition = myIndex;
-                thingToPush.layerData.trackPosition = myIndex;
-                this.arrLayers.splice(myIndex, 0, thingToPush);
-            } else {
-                thingToPush.layerData.layerPosition = myIndex;
-                this.arrLayers.splice(myIndex, 0, thingToPush);
-
-            }
-            this.selectLayer(myIndex, false);
-        }
-    },
-
-    restoreLayer:{
-        value:function (ele) {
-
-            var newLayerName, thingToPush = this.createLayerTemplate();
-
-            this.currentLayerNumber = this.currentLayerNumber + 1;
-            newLayerName = "Layer " + this.currentLayerNumber;
-
-            if(ele.dataset.storedLayerName){
-                newLayerName = ele.dataset.storedLayerName;
-            }
-            thingToPush.layerData.layerName = newLayerName;
-            thingToPush.layerData.layerID = this.currentLayerNumber;
-            thingToPush.layerData.layerTag = "<" + ele.nodeName.toLowerCase() + ">";
-            thingToPush.parentElement = this.application.ninja.currentSelectedContainer;
-            if (this.checkable_animated.classList.contains("checked")) {
-            	thingToPush.layerData.isVisible = false;
-            }
-            // Are there styles to add?
-            thingToPush.layerData.arrLayerStyles = this.createLayerStyles();
-            thingToPush.layerData.arrStyleTracks = this.createStyleTracks();
-
-            if (this._openDoc) {
-                thingToPush.layerData.elementsList.push(ele);
-            }
-
-            this.temparrLayers.splice(0, 0, thingToPush);
-            thingToPush.layerData.trackPosition = this.temparrLayers.length - 1;
-            thingToPush.layerData.layerPosition = this.temparrLayers.length - 1;
-
-            this._openDoc = false;
-
-        }
-    },
-
-    deleteLayer:{
-        value:function (arrElements) {
-            // Only delete a selected layers.  If no layers are selected, do nothing.
-            var i = 0,
-            	arrLayers = document.querySelectorAll(".container-layers .container-layer"),
-            	arrLayersLength = arrLayers.length;
-
-            for (i = arrLayersLength -1; i >= 0; i--) {
-            	if (arrLayers[i].classList.contains("selected")) {
-            		this.arrLayers.splice(i, 1);
-            	}
-            }
-            
-            this.currentLayerSelected = false;
-            this.currentLayersSelected = false;
-            this.resetMasterDuration();
-            	
-            	
-            /*
-            var length = elements.length;
-
-            while(length>0){
-                if (this.layerRepetition.selectedIndexes.length > 0) {
-                    // Delete the selected layer.
-                    var myIndex = this.layerRepetition.selectedIndexes[0];
-                    this.arrLayers.splice(myIndex, 1);
-                    var selectIndex = this.arrLayers.length;
-                    this.resetMasterDuration();
-                    if(selectIndex>0){
-                        this.selectLayer(selectIndex-1);
-                    }
-                    length--;
-                }
-            }
-            */
-        }
-    },
-
-    resetMasterDuration:{
-        value:function(){
-            var trackDuration = 0,
-            	arrLayersLength = this.arrLayers.length, 
-            	i = 0;
-
-            if (arrLayersLength > 0) {
-            	for (i = 0; i < arrLayersLength; i++) {
-            		var currLength = this.arrLayers[i].layerData.trackDuration;
-            		if (currLength > trackDuration) {
-            			trackDuration = currLength;
-            		}
-            	}
-            }
-            this.masterDuration = trackDuration;
-        }
-    },
-
-    handleElementAdded:{
-        value:function() {
-            this.createNewLayer(this.application.ninja.selectedElements[0]);
-
-            if (typeof(this.currentLayerSelected) === "undefined") {
-            	// Edge case: currentLayerSelected needs to be initialized.
-            	this.currentLayerSelected = {};
-            	this.currentLayerSelected.layerData = {};
-            	this.currentLayerSelected.layerData.elementsList = [];
-            }
-            this.currentLayerSelected.layerData.elementsList.push(this.application.ninja.selectedElements[0]);
-            this.currentLayerSelected.layerData.elementsList[0].dataset.storedLayerName = this.currentLayerSelected.layerData.layerName;
-        }
-    },
-
-    handleElementsRemoved:{
-        value:function (event) {
-            var deleteElements = event.detail;
-            //console.log("TimelinePanel.handleElementsRemoved; event.detail is ", event.detail);
-            //debugger;
-            this.deleteLayer(deleteElements);
-        }
-    },
-
-    handleElementReplaced:{
-        value:function(event){
-            this.currentLayerSelected.layerData.elementsList.pop();
-            this.currentLayerSelected.layerData.elementsList.push(event.detail.data.newChild);
-            this.currentLayerSelected.layerData.animatedElement = event.detail.data.newChild;
-        }
-    },
-
-    drawTimeMarkers:{
-        value:function () {
-            this.timeMarkerHolder = document.createElement("div");
-
-            if(this.time_markers.children[0]){
-               this.time_markers.removeChild(this.time_markers.children[0]);
-            }
-
-            this.time_markers.appendChild(this.timeMarkerHolder);
-            var i;
-            var totalMarkers = Math.floor(this.time_markers.offsetWidth / 80);
-            for (i = 0; i < totalMarkers; i++) {
-                var timeMark = document.createElement("div");
-                var markValue = this.calculateTimeMarkerValue(i);
-                timeMark.className = "timemark";
-                timeMark.innerHTML = markValue;
-                this.timeMarkerHolder.appendChild(timeMark);
-            }
-        }
-    },
-
-    calculateTimeMarkerValue:{
-        value:function (currentMarker) {
-            var currentMilliseconds = currentMarker * this.millisecondsOffset;
-            return this.convertMillisecondsToTime(currentMilliseconds);
-        }
-    },
-
-    updateTimeText:{
-        value:function (millisec) {
-            this.timetext.innerHTML = this.convertMillisecondsToTime(millisec);
-        }
-    },
-
-    convertMillisecondsToTime:{
-        value:function(millisec){
-            var timeToReturn;
-            var sec = (Math.floor((millisec / 1000))) % 60;
-            var min = (Math.floor((millisec / 1000) / 60)) % 60;
-            var milliSeconds = String(Math.round(millisec / 10));
-            var returnMillisec = milliSeconds.slice(milliSeconds.length - 2, milliSeconds.length);
-            var returnSec;
-            var returnMin;
-            if (sec < 10) {
-                returnSec = "0" + sec;
-            } else {
-                returnSec = sec;
-            }
-            if (min < 10) {
-                returnMin = "0" + min;
-            } else {
-                returnMin = min;
-            }
-            if (returnMillisec == "0") {
-                returnMillisec = "0" + returnMillisec;
-            }
-            timeToReturn = returnMin + ":" + returnSec + ":" + returnMillisec;
-            return timeToReturn;
-        }
-    },
-
-    createLayerHashTable:{
-        value:function (key, value) {
-            var hashLayerObject;
-            hashLayerObject = Object.create(Object.prototype, {
-                counter:{
-                    value:0,
-                    writable:true
-                },
-
-                setItem:{
-                    value:function (key, value, index) {
-                        if (hashLayerObject[key] === undefined) {
-                            hashLayerObject[key] = {};
-                        }
-                        if (hashLayerObject[key][index] !== undefined) {
-
-
-                            for (this.counter = index; hashLayerObject[key][this.counter]; this.counter++) {
-                            }
-
-                            for (; this.counter !== index; this.counter--) {
-                                hashLayerObject[key][this.counter] = hashLayerObject[key][this.counter - 1];
-                            }
-                        }
-                        hashLayerObject[key][index] = value;
-                        this.counter = 0;
-                    }
-                },
-
-                getItem:{
-                    value:function (key) {
-                        return hashLayerObject[key];
-                    }
-                }
-            });
-            return hashLayerObject;
-        }
-    },
-
-    selectLayer:{
-        value:function (layerIndex, userSelection) {
-
-            var i = 0;
-            var arrLayersLength = this.arrLayers.length;
-
-            if (this.selectedKeyframes) {
-                this.deselectTweens();
-            }
-
-            for (i = 0; i < arrLayersLength; i++) {
-                if (i === layerIndex) {
-                    this.arrLayers[i].layerData.isSelected = true;
-                } else {
-                    this.arrLayers[i].layerData.isSelected = false;
-                }
-                
-                this.triggerLayerBinding(i);
-            }
-
-            this.layerRepetition.selectedIndexes = [layerIndex];
-            this.currentLayerSelected = this.arrLayers[layerIndex];
-            if (userSelection) {
-                if (this._captureSelection) {
-
-                    if (this.currentLayerSelected.layerData.elementsList.length >= 1) {
-                        this.application.ninja.selectionController.selectElements(this.currentLayerSelected.layerData.elementsList);
-                    } else {
-                        this.application.ninja.selectionController.executeSelectElement();
-                    }
-
-                }
-                this._captureSelection = true;
-            }
-            this.resetMasterDuration();
-        }
-    },
-
-    getLayerIndexByID:{
-        value:function (layerID, tempArr) {
-            var i = 0,
-                returnVal = false,
-                arrLayersLength = this.arrLayers.length;
-
-            if (tempArr) {
-                var tempArrLength = this.temparrLayers.length;
-
-                for (i = 0; i < tempArrLength; i++) {
-                    if (this.temparrLayers[i].layerData.layerID === layerID) {
-                        returnVal = i;
-                    }
-                }
-
-            } else {
-                for (i = 0; i < arrLayersLength; i++) {
-                    if (this.arrLayers[i].layerData.layerID === layerID) {
-                        returnVal = i;
-                    }
-                }
-            }
-            return returnVal;
-        }
-    },
-
-    getLayerIndexByName:{
-        value:function (layerName) {
-            var i = 0,
-                returnVal = false,
-                arrLayersLength = this.arrLayers.length;
-
-            for (i = 0; i < arrLayersLength; i++) {
-                if (this.arrLayers[i].layerData.layerName === layerName) {
-                    returnVal = i;
-                }
-            }
-            return returnVal;
-        }
-    },
-
-    getActiveLayerIndex:{
-        value:function () {
-            var i = 0,
-                returnVal = false,
-                arrLayersLength = this.arrLayers.length;
-            for (i = 0; i < arrLayersLength; i++) {
-                if (this.arrLayers[i].layerData.isActive === true) {
-                    returnVal = i;
-                    this.arrLayers[i].layerData.isActive = false;
-                }
-            }
-            return returnVal;
-        }
-    },
-
-    enablePanel:{
-        value:function (boolEnable) {
-            if (boolEnable) {
-                this.timeline_disabler.style.display = "none";
-            } else {
-                this.timeline_disabler.style.display = "block";
-            }
-        }
-    },
-    handleConfigButtonClick: {
-    	value: function(event) {
-    		event.stopPropagation();
-    		this.handleCheckableClick(event);
-    		
-    	}
-    },
-    handleDocumentClick: {
-    	value: function(event) {
-    		if (this.tl_configbutton.classList.contains("checked")) {
-    			this.tl_configbutton.classList.remove("checked");
-    		}
-    	}
-    },
-    
-    handleAnimatedClick: {
-    	value: function(event) {
-    		if (typeof(this.application.ninja.currentDocument) === "undefined") {
-    			return;
-    		}
-    		if (this.application.ninja.currentDocument == null) {
-    			return;
-    		}
-    		this.handleCheckableClick(event);
-    		this.application.ninja.currentDocument.boolShowOnlyAnimated = event.currentTarget.classList.contains("checked");
-    		var boolHide = false,
-    			i = 0,
-    			arrLayersLength = this.arrLayers.length;
-    		if (event.currentTarget.classList.contains("checked")) {
-    			// Hide layers with isAnimated = false;
-    			boolHide = true;
-    		}
-    		
-    		for (i = 0; i < arrLayersLength; i++) {
-    			if (boolHide) {
-    				// Hide layers with isAnimated = false
-    				if (this.arrLayers[i].layerData.isTrackAnimated === false) {
-    					this.arrLayers[i].layerData.isVisible = false;
-    					this.triggerLayerBinding(i);
-    				}
-    			} else {
-    				this.arrLayers[i].layerData.isVisible = true;
-    				this.triggerLayerBinding(i);
-    			}
-    		}
-    		
-    	}
-    },
-    handleRelativeClick: {
-    	value: function(event) {
-    		if (!event.currentTarget.classList.contains("checked")) {
-    			this.handleCheckableClick(event);
-    		}
-    		this.checkable_absolute.classList.remove("checked");
-            this.useAbsolutePosition = false;
-    	}
-    },
-    handleAbsoluteClick: {
-    	value: function(event) {
-    		if (!event.currentTarget.classList.contains("checked")) {
-    			this.handleCheckableClick(event);
-    		}
-    		this.checkable_relative.classList.remove("checked");
-            this.useAbsolutePosition = true;
-    	}
-    },
-    handleCheckableClick: {
-    	value: function(event) {
-    		if (event.currentTarget.classList.contains("checked")) {
-    			event.currentTarget.classList.remove("checked");
-    		} else {
-    			event.currentTarget.classList.add("checked");
-    		}
-    	}
-    },
-    // Trigger the layer/track data binding
-    triggerLayerBinding : {
-    	value: function(intIndex) {
-            this.arrLayers[intIndex].layerData.triggerBinding = !this.arrLayers[intIndex].layerData.triggerBinding;
-        }
-    },
-    
-    handleLayerDragStart : {
-    	value: function(event) {
-            var dragIcon = document.createElement("img");
-            event.dataTransfer.effectAllowed = 'move';
-            event.dataTransfer.setData('Text', this.identifier);
-            // dragIcon.src = "/images/transparent.png";
-            dragIcon.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAA1JREFUGFdj+P//PwMACPwC/ohfBuAAAAAASUVORK5CYII="
-            dragIcon.width = 1;
-            event.dataTransfer.setDragImage(dragIcon, 0, 0);
-            
-            // Clone the element we're dragging
-            this._dragAndDropHelper = event.target.cloneNode(true);
-            this._dragAndDropHelper.style.opacity = 0.8;
-            this._dragAndDropHelper.style.position = "absolute";
-            this._dragAndDropHelper.style.top = "0px";
-            this._dragAndDropHelper.style.left = "0px";
-            this._dragAndDropHelper.style.zIndex = 700;
-            
-            this._dragAndDropHelper.style.width = window.getComputedStyle(this.container_layers, null).getPropertyValue("width");
-            this._dragAndDropHelper.classList.add("timeline-dnd-helper");
-            
-            // Get the offset 
-    		var findYOffset = function(obj) {
-				var curleft = curtop = 0;
-				
-				if (obj.offsetParent) {
-					do {
-							curleft += obj.offsetLeft;
-							curtop += obj.offsetTop;
-				
-						} while (obj = obj.offsetParent);
-				}
-				return curtop;
-    		}
-    		this._dragAndDropHelperOffset = findYOffset(this.container_layers);
-    		this._appendHelper = true;
-    		this._deleteHelper = false;
-    	}
-    },
-    handleLayerDragover: {
-    	value: function(event) {
-    		var currPos = 0,
-    			myScrollTest = ((event.y - (this._dragAndDropHelperOffset - this.user_layers.scrollTop)) + 28) - this.user_layers.scrollTop;
-    		if ((myScrollTest < 60) && (this.user_layers.scrollTop >0)) {
-    			this._scrollTracks = (this.user_layers.scrollTop - 10)
-    		}
-    		if ((myScrollTest < 50) && (this.user_layers.scrollTop >0)) {
-    			this._scrollTracks = (this.user_layers.scrollTop - 20)
-    		}
-    		if ((myScrollTest > (this.user_layers.clientHeight + 10))) {
-    			this._scrollTracks = (this.user_layers.scrollTop + 10)
-    		}
-    		if ((myScrollTest > (this.user_layers.clientHeight + 20))) {
-    			this._scrollTracks = (this.user_layers.scrollTop + 20)
-    			
-    		}
-    		currPos = event.y - (this._dragAndDropHelperOffset - this.user_layers.scrollTop)- 28;
-    		this._dragAndDropHelperCoords = currPos + "px";
-    		this.needsDraw = true;
-    	}
-    },
-    handleLayerDragEnd : {
-    	value: function(event) {
-    		this._deleteHelper = true;
-    		this.needsDraw = true;
-           
-    	}
-    },
-    handleLayerDrop : {
-    	value: function(event) {
-            event.stopPropagation();
-            event.preventDefault();
-            this._deleteHelper = true; 
-            this.needsDraw = true;
-    	}
-    },
-    /* === END: Controllers === */
-
-    /* === BEGIN: Logging routines === */
-    _boolDebug:{
-        enumerable:false,
-        value:false // set to true to enable debugging to console; false for turning off all debugging.
-    },
-    boolDebug:{
-        get:function () {
-            return this._boolDebug;
-        },
-        set:function (boolDebugSwitch) {
-            this._boolDebug = boolDebugSwitch;
-        }
-    },
-    log:{
-        value:function (strMessage) {
-            if (this.boolDebug) {
-                console.log(this.getLineNumber() + ": " + strMessage);
-            }
-        }
-    },
-    getLineNumber:{
-        value:function () {
-            try {
-                throw new Error('bazinga')
-            } catch (e) {
-                return e.stack.split("at")[3].split(":")[2];
-            }
-        }
-    }
-    /* === END: Logging routines === */
+/* <copyright>
+ This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
+ (c) Copyright 2011 Motorola Mobility, Inc.  All Rights Reserved.
+ </copyright> */
+
+var Montage = require("montage/core/core").Montage;
+var Component = require("montage/ui/component").Component;
+var nj = require("js/lib/NJUtils").NJUtils;
+
+var TimelinePanel = exports.TimelinePanel = Montage.create(Component, {
+
+    hasTemplate:{
+        value:true
+    },
+
+    /* === BEGIN: Models === */
+    _currentDocument: {
+        value : null
+    },
+
+    currentDocument : {
+        get : function() {
+            return this._currentDocument;
+        },
+        set : function(value) {
+            // If it's the same document, do nothing.
+            if (value === this._currentDocument) {
+                return;
+            }
+
+            if(!this._currentDocument && value.currentView === "design") {
+                this.enablePanel(true);
+            }
+
+            this._currentDocument = value;
+
+            if(!value) {
+                this._boolCacheArrays = false;
+                this.clearTimelinePanel();
+                this._boolCacheArrays = true;
+                this.enablePanel(false);
+            } else if(this._currentDocument.currentView === "design") {
+                this._boolCacheArrays = false;
+                this.clearTimelinePanel();
+                this._boolCacheArrays = true;
+
+                // Rebind the document events for the new document context
+                this._bindDocumentEvents();
+                
+                // Initialize the timeline for the document.
+                this.initTimelineForDocument();
+            }
+        }
+    },
+    
+    _currentSelectedContainer: {
+        value: null
+    },
+    currentSelectedContainer: {
+        get: function() {
+            return this._currentSelectedContainer;
+        },
+        set: function(newVal) {
+            if(this._currentSelectedContainer !== newVal) {
+                this._currentSelectedContainer = newVal;
+                if (this._ignoreNextContainerChange === true) {
+                    this._ignoreNextContainerChange = false;
+                    return;
+                }
+                this.application.ninja.currentDocument.setLevel = true;
+                
+                if(this._currentDocument.currentView === "design") {
+                    this._boolCacheArrays = false;
+                    this.clearTimelinePanel();
+                    this._boolCacheArrays = true;
+    
+                    // Rebind the document events for the new document context
+                    this._bindDocumentEvents();
+                    
+                    // Initialize the timeline for the document.
+                    this.initTimelineForDocument();
+                }
+            }
+        }
+    },
+
+    _arrLayers:{
+        value:[]
+    },
+
+    arrLayers:{
+        serializable:true,
+        get:function () {
+            return this._arrLayers;
+        },
+        set:function (newVal) {
+            this._arrLayers = newVal;
+            this.needsDraw = true;
+            this.cacheTimeline();
+        }
+    },
+
+    _temparrLayers:{
+        value:[]
+    },
+
+    temparrLayers:{
+        get:function () {
+            return this._temparrLayers;
+        },
+        set:function (newVal) {
+            this._temparrLayers = newVal;
+        }
+    },
+
+
+    _layerRepetition:{
+        value:null
+    },
+
+    layerRepetition:{
+        get:function () {
+            return this._layerRepetition;
+        },
+        set:function (newVal) {
+            this._layerRepetition = newVal;
+        }
+    },
+
+    // Set to false to skip array caching array sets in current document
+    _boolCacheArrays:{
+        value:true
+    },
+
+    _currentLayerNumber:{
+        value:0
+    },
+
+    currentLayerNumber:{
+        get:function () {
+            return this._currentLayerNumber;
+        },
+        set:function (newVal) {
+            if (newVal !== this._currentLayerNumber) {
+                this._currentLayerNumber = newVal;
+                this.cacheTimeline();
+            }
+        }
+    },
+
+    _currentLayerSelected:{
+        value: false
+    },
+    currentLayerSelected:{
+        get:function () {
+            return this._currentLayerSelected;
+        },
+        set:function (newVal) {
+            this._currentLayerSelected = newVal;
+            this.cacheTimeline();
+        }
+    },
+
+    _selectedLayerID:{
+        value:false
+    },
+    selectedLayerID:{
+        get:function () {
+            return this._selectedLayerID;
+        },
+        set:function (newVal) {
+            if (newVal === false) {
+                // We are clearing the timeline, so just set the value and return.
+                this._selectedLayerID = newVal;
+                return;
+            }
+            if (newVal !== this._selectedLayerID) {
+                var selectIndex = this.getLayerIndexByID(newVal);
+                this._selectedLayerID = newVal;
+                this._captureSelection = true;
+                if (this.currentLayerSelected !== false) {
+                	this.selectLayer(selectIndex, false);
+                }
+                if (this.currentLayersSelected !== false) {
+                	this.selectLayers(this.currentLayersSelected);
+                }
+                if ((this.currentLayersSelected === false) && (this.currentLayerSelected === false)) {
+                	this.selectLayers([]);
+                }
+                
+            }
+        }
+    },
+
+    _currentLayersSelected:{
+        value:[]
+    },
+    currentLayersSelected:{
+        get:function () {
+            return this._currentLayersSelected;
+        },
+        set:function (newVal) {
+            this._currentLayersSelected = newVal;
+            this.cacheTimeline();
+        }
+    },
+
+
+    _millisecondsOffset:{
+        value:1000
+    },
+
+    millisecondsOffset:{
+        get:function () {
+            return this._millisecondsOffset;
+    },
+        set:function (newVal) {
+            if (newVal !== this._millisecondsOffset) {
+                this._millisecondsOffset= newVal;
+                this.drawTimeMarkers();
+                NJevent('tlZoomSlider',this);
+            }
+        }
+    },
+
+    _masterDuration:{
+        value:0
+    },
+
+    masterDuration:{
+        serializable:true,
+        get:function () {
+            return this._masterDuration;
+        },
+        set:function (val) {
+            this._masterDuration = val;
+            this.timebar.style.width = (this._masterDuration / 12) + "px";
+        }
+    },
+
+    _trackRepetition:{
+        value:null
+    },
+
+    trackRepetition:{
+        get:function () {
+            return this._trackRepetition;
+        },
+        set:function (newVal) {
+            this._trackRepetition = newVal;
+        }
+    },
+
+    _selectedKeyframes:{
+        value:[]
+    },
+
+    selectedKeyframes:{
+        serializable:true,
+        get:function () {
+            return this._selectedKeyframes;
+        },
+        set:function (newVal) {
+            this._selectedKeyframes = newVal;
+        }
+    },
+
+    _selectedTweens:{
+        value:[]
+    },
+
+    selectedTweens:{
+        serializable:true,
+        get:function () {
+            return this._selectedTweens;
+        },
+        set:function (newVal) {
+            this._selectedTweens = newVal;
+        }
+    },
+
+    _breadCrumbContainer:{
+            value:null
+    },
+
+    breadCrumbContainer:{
+        get:function () {
+            return this._breadCrumbContainer;
+        },
+        set:function (value) {
+            if (this._breadCrumbContainer !== value) {
+                this._breadCrumbContainer = value;
+            }
+        }
+    },
+
+    _isLayer:{
+        value:false
+    },
+
+    _firstTimeLoaded:{
+        value:true
+    },
+
+    _captureSelection:{
+        value:false
+    },
+
+    _openDoc:{
+        value:false
+    },
+
+    timeMarkerHolder:{
+        value:null
+    },
+    _dragAndDropHelper : {
+    	value: false
+    },
+    _dragAndDropHelperCoords: {
+    	value: false
+    },
+    _dragAndDropHelperOffset : {
+    	value: false
+    },
+    _dragLayerID : {
+    	value: null
+    },
+
+    layersDragged:{
+           value:[],
+           writable:true
+    },
+
+    dragLayerID : {
+    	get: function() {
+    		return this._dragLayerID;
+    	},
+    	set: function(newVal) {
+    		if (newVal !== this._dragLayerID) {
+    			this._dragLayerID = newVal;
+    		}
+    	}
+    },
+    _dropLayerID : {
+    	value: null
+    },
+    dropLayerID : {
+    	get: function() {
+    		return this._dropLayerID;
+    	},
+    	set: function(newVal) {
+    		if (newVal !== this._dropLayerID) {
+    			this._dropLayerID = newVal;
+    			
+    			var dragLayerIndex = this.getLayerIndexByID(this.dragLayerID),
+    				dropLayerIndex = this.getLayerIn