







































Module('ca.carleton.gcrc.atlas.widgets.timeline','$Revision: 3866 $',function(mod){

var modObservable=imprt('ca.carleton.gcrc.mvc.observable');
var modDisplayWidget=imprt('ca.carleton.gcrc.atlas.displayWidget');





mod.Factory=Class(modDisplayWidget.WidgetFactory,function(publ,priv,supr){








publ.__init__=function(
layerName_,
timeAttribute_,
currentTimeLayerName_,
currentTimeFeatureName_,
currentTimeAttributeName_,
labelAttributeName_
){

supr.__init__.call(this);




this.layerName=layerName_;




this.timeAttribute=timeAttribute_;




this.labelAttributeName=labelAttributeName_;




this.currentTimeLayerName=currentTimeLayerName_;




this.currentTimeFeatureName=currentTimeFeatureName_;




this.currentTimeAttributeName=currentTimeAttributeName_;




this.focusTimeLayerName=null;




this.focusTimeFeatureName=null;




this.focusTimeAttributeName=null;
}




publ.IsSVG=function()
{
return true;
}





publ.Width=function()
{
return 0;
}





publ.Height=function()
{
return 0;
}








publ.AddFocusTime=function(layerName_,featureName_,attributeName_)
{
this.focusTimeLayerName=layerName_;
this.focusTimeFeatureName=featureName_;
this.focusTimeAttributeName=attributeName_;
}











publ.Create=function(
svgParent_,
dataModel_,
x_,
y_,
width_,
height_
)
{
return new mod.Timeline(
this,
svgParent_,
dataModel_,
x_,
y_,
width_,
height_
);
}

});






mod.Timeline=Class(modObservable.Observer,function(publ,priv,supr){










publ.__init__=function(
factory_,
svgParent_,
dataModel_,
x_,
y_,
width_,
height_
){

supr.__init__.call(this);




this.svgParentElement=svgParent_;




this.dataModel=dataModel_;




this.x=x_;




this.y=y_;




this.width=width_;




this.height=height_;




this.layer=this.dataModel.LayerFromName(factory_.layerName);




this.attributeName=factory_.timeAttribute;




this.currentTimeFeature=this.dataModel.LayerFromName(factory_.currentTimeLayerName).FeatureFromId(factory_.currentTimeFeatureName);




this.currentTimeAttribute=factory_.currentTimeAttributeName;




this.labelAttribute=factory_.labelAttributeName;




this.focusTimeFeature=null;
if(null!=factory_.focusTimeLayerName
&&null!=factory_.focusTimeFeatureName
&&null!=factory_.focusTimeAttributeName)
{
this.focusTimeFeature=this.dataModel.LayerFromName(factory_.focusTimeLayerName).FeatureFromId(factory_.focusTimeFeatureName);
}




this.focusTimeAttribute=factory_.focusTimeAttributeName;




this.topGroup=null;
this.buttonsGroup=null;
this.buttonsByName={};
this.textByName={};

this.textHeight=10;
this.textSpacing=2;

this.colourUnselected='#ffffff';
this.colourInFocus='#4d4d4d';
this.colourSelected='#0092ff';
this.colourSelectedInFocus='#0062df';


this.currentTime=this.currentTimeFeature.GetVariableValue(this.currentTimeAttribute);
this.Observe(this.currentTimeFeature,this.currentTimeAttribute,this.CurrentTimeChanged,null);


this.currentFocus=null;
if(null!=this.focusTimeFeature)
{
this.currentFocus=this.focusTimeFeature.GetVariableValue(this.focusTimeAttribute);
this.Observe(this.focusTimeFeature,this.focusTimeAttribute,this.FocusTimeChanged,null);
}


this.timesComputingRequired=true;
this.Observe(this.layer,this.attributeName,this.TimesChanged,null);
if(null!=this.labelAttribute)
{
this.Observe(this.layer,this.labelAttribute,this.TimesChanged,null);
}

this.redrawRequired=true;
this.Redraw();
}

publ.CurrentTimeChanged=function(mvcEvent_)
{
var previousTime=this.currentTime;
this.currentTime=mvcEvent_.data;
this.ApplyColour(previousTime);
this.ApplyColour(this.currentTime);
}

publ.FocusTimeChanged=function(mvcEvent_)
{
var previousTime=this.currentFocus;
this.currentFocus=mvcEvent_.data;
this.ApplyColour(previousTime);
this.ApplyColour(this.currentFocus);
}

publ.TimesChanged=function(mvcEvent_)
{
this.timesComputingRequired=true;
this.Redraw();
}

publ.Remove=function()
{

this.Terminate();


this.Erase();
}

publ.Erase=function()
{
if(null!=this.topGroup)
{
if(null!=this.buttonsGroup)
{
this.buttonsGroup.removeEventListener('click',this,false);
this.buttonsGroup.removeEventListener('onmouseover',this,false);
this.buttonsGroup.removeEventListener('onmouseout',this,false);
this.buttonsGroup=null;
}

this.svgParentElement.removeChild(this.topGroup);
this.topGroup=null;

this.buttonsByName={};
this.textByName={};
}
}

publ.Redraw=function(){
if(this.timesComputingRequired||this.redrawRequired){
if(false==this.dataModel.busy){
if(this.timesComputingRequired){
this.ComputeTimes();
this.timesComputingRequired=false;
this.redrawRequired=true;
}

if(this.redrawRequired){
this.Erase();
this.Draw();
this.redrawRequired=false;
}
}else{
var receiver=this;
this.dataModel.RegisterForEndProcessing(function(){
receiver.Redraw();
});
}
}
}

publ.Draw=function()
{
var doc=this.svgParentElement.ownerDocument;
var ns=this.svgParentElement.namespaceURI;


var x_offset=1;
var total_width_per_feature;
if(this.times.length<1)
{
total_width_per_feature=this.width-x_offset;
}
else
{
total_width_per_feature=(this.width-x_offset)/this.times.length;
}
var x_width=total_width_per_feature-(2*x_offset);
var y_offset=this.textHeight;
var y_height=this.height-(2*this.textHeight);

var text_x_offset=total_width_per_feature/2;
var text_y_offset_odd=y_offset-this.textSpacing;
var text_y_offset_even=y_offset+y_height+this.textHeight;


this.topGroup=doc.createElementNS(ns,'g');
this.svgParentElement.appendChild(this.topGroup);


var background=doc.createElementNS(ns,'rect');
background.setAttributeNS(null,'x',this.x);
background.setAttributeNS(null,'y',this.y+y_offset);
background.setAttributeNS(null,'width',this.width);
background.setAttributeNS(null,'height',y_height);
background.setAttributeNS(null,'fill','#cccccc');
this.topGroup.appendChild(background);


this.buttonsGroup=doc.createElementNS(ns,'g');
this.buttonsGroup.addEventListener('click',this,false);
this.buttonsGroup.addEventListener('mouseover',this,false);
this.buttonsGroup.addEventListener('mouseout',this,false);
this.topGroup.appendChild(this.buttonsGroup);


var loop;
for(loop=0;loop<this.times.length;++loop)
{
var time=this.times[loop][0];
var label=this.times[loop][1];

var x=this.x+(loop*total_width_per_feature)+x_offset;
var y=this.y+y_offset;
var text_x=this.x+(loop*total_width_per_feature)+text_x_offset;
var text_y;
if(loop%2)
{
text_y=this.y+text_y_offset_odd;
}
else
{
text_y=this.y+text_y_offset_even;
}

var button=doc.createElementNS(ns,'rect');
button.setAttributeNS(null,'x',x);
button.setAttributeNS(null,'y',y);
button.setAttributeNS(null,'width',x_width);
button.setAttributeNS(null,'height',y_height);
button.setAttributeNS(null,'cursor','pointer');
button.setAttributeNS('timeline','time',time);
this.buttonsGroup.appendChild(button);

var text=doc.createElementNS(ns,'text');
text.setAttributeNS(null,'x',text_x);
text.setAttributeNS(null,'y',text_y);
text.setAttributeNS(null,'text-anchor','middle');
text.setAttributeNS(null,'font-family','Arial');
text.setAttributeNS(null,'font-size','11');
text.setAttributeNS(null,'cursor','pointer');
text.setAttributeNS('timeline','time',time);
text.appendChild(doc.createTextNode(label));
this.buttonsGroup.appendChild(text);

this.buttonsByName[time]=button;
this.textByName[time]=text;
this.ApplyColour(time);
}
}

publ.ComputeTimes=function()
{
var IMPOSSIBLE_MARKER='*';






var accumulator={};


var features=this.layer.Features();
var featureIndex;
for(featureIndex=0;featureIndex<features.length;++featureIndex)
{
var feature=features[featureIndex];

var timeValue=feature.GetVariableValue(this.attributeName);
if(null!=timeValue)
{
var labelValue=null;
if(null!=this.labelAttribute)
{
labelValue=feature.GetVariableValue(this.labelAttribute);
}
if(null==labelValue)
{
labelValue=IMPOSSIBLE_MARKER;
}

if(IMPOSSIBLE_MARKER==accumulator[timeValue]||null==accumulator[timeValue])
{
accumulator[timeValue]=labelValue;
}
}
}


var allValues=new Array();
var timeValue;
for(timeValue in accumulator)
{
var labelValue=accumulator[timeValue];
if(IMPOSSIBLE_MARKER==labelValue)
{
labelValue=timeValue;
}

allValues.push([timeValue,labelValue]);
}


this.times=allValues.sort(mod.TimelineSort);
}

mod.TimelineSort=function(a,b){
var timeValueA=a[0];
var timeValueB=b[0];

if(isNaN(timeValueA)||isNaN(timeValueB)){
if(timeValueA<timeValueB)return-1;
if(timeValueA>timeValueB)return 1;
}else{
var valA=1*timeValueA;
var valB=1*timeValueB;

if(valA<valB)return-1;
if(valA>valB)return 1;
}
return 0;
}

publ.handleEvent=function(event_)
{

var type=event_.type


var element=event_.target;


var time=element.getAttributeNS('timeline','time');


if(null!=time)
{

if('click'==type)
{
this.currentTimeFeature.SetVariableValue(this.currentTimeAttribute,time);
}
else if('mouseover'==type)
{

if(null!=this.focusTimeFeature)
{
this.focusTimeFeature.SetVariableValue(this.focusTimeAttribute,time);
}
else
{
this.currentFocus=time;
this.ApplyColour(time);
}
}
else if('mouseout'==type)
{

if(time==this.currentFocus)
{
if(null!=this.focusTimeFeature)
{
this.focusTimeFeature.SetVariableValue(this.focusTimeAttribute,null);
}
else
{
this.currentFocus=null;
this.ApplyColour(time);
}
}
else
{

this.ApplyColour(time);
}
}
}
}

publ.ApplyColour=function(time_)
{
var inFocus=(time_==this.currentFocus);
var selected=(time_==this.currentTime);


var fill;
var textFill;
if(true==inFocus&&true==selected)
{
fill=this.colourSelectedInFocus;
textFill=this.colourSelectedInFocus;
}
else if(true==selected)
{
fill=this.colourSelected;
textFill=this.colourSelected;
}
else if(true==inFocus)
{
fill=this.colourInFocus;
textFill=this.colourInFocus;
}
else
{
fill=this.colourUnselected;
textFill='#000000';
}


var button=this.buttonsByName[time_];
if(null!=button)
{
button.setAttributeNS(null,'fill',fill);
}


var text=this.textByName[time_];
if(null!=text)
{
text.setAttributeNS(null,'fill',textFill);
}
}
});
});