/**
* Used to build and manage widgets.
*
* @author J Clare
* @class ia.Report
* @extends ia.EventDispatcher
* @constructor
* @param {JQUERY Element} reportContainer The report container.
*/
ia.Report = function(reportContainer)
{
ia.Report.baseConstructor.call(this);
this._widgetArray = [];
this._widgetHash = new Object();
this._panelArray = [];
this._panelHash = new Object();
this._buttonArray = [];
this._buttonHash = new Object();
this._textArray = [];
this._textHash = new Object();
this._imageArray = [];
this._imageHash = new Object();
this._calloutArray = [];
this._calloutHash = new Object();
this._componentArray = [];
this._componentHash = new Object();
this.selectionColor = "#ff0000";
this.highlightColor = "#00ff00";
this.selectionOpacity = 0.3;
this.highlightOpacity = 0.3;
this.uid = "";
this.evaluation = true;
// Report config.
this.config = new ia.ReportConfig();
// Text substitution.
this.textSubstitution = new ia.TextSubstitution();
this.container = $j('<div id="ia-report" class="ia-report">');
reportContainer.append(this.container);
// Add the busy container.
this.$busyContainer = $j('<div class="ia-report-busy">');
this.$busyContainer.bind(ia.CLICK_TYPE, function(e) {event.stopPropagation();});
this.$busyContainer.bind("touchstart touchmove touchend mousemove mouseup mouseenter mouseleave mousedown click", function(e)
{
e.stopPropagation();
});
reportContainer.append(this.$busyContainer);
// Add the progress container.
this.$progressContainer = $j('<div class="ia-report-loading">');
this.$progressContainer.bind(ia.CLICK_TYPE, function(e) {event.stopPropagation();});
this.$progressContainer.bind("touchstart touchmove touchend mousemove mouseup mouseenter mouseleave mousedown click", function(e)
{
e.stopPropagation();
});
reportContainer.append(this.$progressContainer);
};
ia.extend(ia.EventDispatcher, ia.Report);
/**
* The container that holds the object.
*
* @property container
* @type JQUERY Element
*/
ia.Report.prototype.container;
/**
* The report config object.
*
* @property config
* @type ia.ReportConfig
*/
ia.Report.prototype.config;
/**
* An ArcGIS Web Map object.
*
* @property webMapData
* @type ia.WebMapData
*/
ia.Report.prototype.webMapData;
/**
* The report data object.
*
* @property data
* @type ia.ReportData
*/
ia.Report.prototype.data;
/**
* The report locale object.
*
* @property locale
* @type ia.Locale
*/
ia.Report.prototype.locale;
/**
* The report text substitution object.
*
* @property textSubstitution
* @type ia.TextSubstitution
*/
ia.Report.prototype.textSubstitution;
/**
* The report url object.
*
* @property url
* @type ia.UrlParams
*/
ia.Report.prototype.url;
/**
* The report selection color.
*
* @property selectionColor
* @type String
*/
ia.Report.prototype.selectionColor;
/**
* The report highlight color.
*
* @property highlightColor
* @type String
*/
ia.Report.prototype.highlightColor;
/**
* The report selection opacity.
*
* @property selectionOpacity
* @type Number
* @default 0.3
*/
ia.Report.prototype.selectionOpacity;
/**
* The report highlight opacity.
*
* @property highlightOpacity
* @type Number
* @default 0.3
*/
ia.Report.prototype.highlightOpacity;
/**
* Unique id.
*
* @property uid
* @type String
* @default ""
*/
ia.Report.prototype.uid;
/**
* Is it an evaluation version.
*
* @property evaluation
* @type Boolean
* @default true
*/
this.evaluation = true;
/**
* The template number.
*
* @property template
* @type String
*/
ia.Report.prototype.template;
/**
* The version number.
*
* @property version
* @type String
*/
ia.Report.prototype.version;
/**
* Adds a component.
*
* @method addComponent
* @param {String} id The component id.
* @param {Object} component The component to add.
*/
ia.Report.prototype.addComponent = function(id, component)
{
this._componentHash[id] = component;
this._componentArray[this._componentArray.length] = component;
};
/**
* Returns all components.
*
* @method getComponents
* @return {Object[]} An array of components.
*/
ia.Report.prototype.getComponents = function() {return this._componentArray;};
/**
* Returns the component that corresponds to the id.
*
* @method getComponent
* @param {String} id The id.
* @return {Object} The component.
*/
ia.Report.prototype.getComponent = function(id) {return this._componentHash[id];};
/**
* Adds a callout.
*
* @method addCallout
* @param {ia.CalloutBox} callout The callout to add.
*/
ia.Report.prototype.addCallout = function(callout)
{
this._calloutArray[this._calloutArray.length] = callout;
this._calloutHash[callout.id] = callout;
this.container.append(callout.container);
};
/**
* Returns all callouts.
*
* @method getCallouts
* @return {ia.CalloutBox[]} An array of callouts.
*/
ia.Report.prototype.getCallouts = function() {return this._calloutArray;};
/**
* Returns the callout that corresponds to the id.
*
* @method getCallout
* @param {String} id The id.
* @return {ia.CalloutBox} The callout.
*/
ia.Report.prototype.getCallout = function(id) {return this._calloutHash[id];};
/**
* Adds a new widget.
*
* @method addWidget
* @param {ia.Widget} widget The widget.
*/
ia.Report.prototype.addWidget = function(widget)
{
this._widgetArray[this._widgetArray.length] = widget;
this._widgetHash[widget.id] = widget;
this.container.append(widget.container);
};
/**
* Returns all widgets.
*
* @method getWidgets
* @return {ia.Widget[]} An array of widgets.
*/
ia.Report.prototype.getWidgets = function() {return this._widgetArray;};
/**
* Returns the widget that corresponds to the id.
*
* @method getWidget
* @param {String} id The id.
* @return {ia.Widget} The widget.
*/
ia.Report.prototype.getWidget = function(id)
{
id = id.replace('-panel', ''); // For backwards compatibility.
return this._widgetHash[id];
};
/**
* Removes all widgets.
*
* @method removeWidgets
*/
ia.Report.prototype.removeWidgets = function()
{
for (var i = 0; i < this._widgetArray.length; i++)
{
var widget = this._widgetArray[i];
widget.container.remove();
}
// Reset arrays
this._panelArray = [];
this._panelHash = new Object();
this._textArray = [];
this._textHash = new Object();
this._imageArray = [];
this._imageHash = new Object();
this._buttonArray = [];
this._buttonHash = new Object();
this._widgetArray = [];
this._widgetHash = new Object();
this._calloutArray = [];
this._calloutHash = new Object();
this._componentArray = [];
this._componentHash = new Object();
};
/**
* Adds a new panel.
*
* @method addPanel
* @param {ia.Panel} panel The panel.
*/
ia.Report.prototype.addPanel = function(panel)
{
this._panelArray[this._panelArray.length] = panel;
this._panelHash[panel.id] = panel;
this.addWidget(panel);
};
/**
* Returns the panels.
*
* @method getPanels
* @return {ia.Panel[]} An array of panels.
*/
ia.Report.prototype.getPanels = function() {return this._panelArray;};
/**
* Returns the panel that corresponds to the id.
*
* @method getPanel
* @param {String} id The id.
* @return {ia.Panel} The panel.
*/
ia.Report.prototype.getPanel = function(id)
{
id = id.replace('-panel', ''); // For backwards compatibility.
return this._panelHash[id];
};
/**
* Adds a new button.
*
* @method addButton
* @param {ia.Button} btn The button.
*/
ia.Report.prototype.addButton = function(btn)
{
this._buttonArray[this._buttonArray.length] = btn;
this._buttonHash[btn.id] = btn;
this.addWidget(btn);
};
/**
* Returns the buttons.
*
* @method getButtons
* @return {ia.Button[]} An array of buttons.
*/
ia.Report.prototype.getButtons = function() {return this._buttonArray;};
/**
* Returns the component that corresponds to the id.
*
* @method getButton
* @param {String} id The id.
* @return {ia.Button} The button.
*/
ia.Report.prototype.getButton = function(id) {return this._buttonHash[id];};
/**
* Adds new text.
*
* @method addText
* @param {ia.Text} txt The text.
*/
ia.Report.prototype.addText = function(txt)
{
this._textArray[this._textArray.length] = txt;
this._textHash[txt.id] = txt;
this.addWidget(txt);
};
/**
* Returns the text.
*
* @method getTexts
* @return {ia.Text[]} An array of text.
*/
ia.Report.prototype.getTexts = function() {return this._textArray;};
/**
* Returns the text that corresponds to the id.
*
* @method getText
* @param {String} id The id.
* @return {ia.Text} The text.
*/
ia.Report.prototype.getText = function(id) {return this._textHash[id];};
/**
* Adds a new image.
*
* @method addImage
* @param {ia.Image} img The image.
*/
ia.Report.prototype.addImage = function(img)
{
this._imageArray[this._imageArray.length] = img;
this._imageHash[img.id] = img;
this.addWidget(img);
};
/**
* Returns the images.
*
* @method getImages
* @return {ia.Image[]} An array of images.
*/
ia.Report.prototype.getImages = function() {return this._imageArray;};
/**
* Returns the image that corresponds to the id.
*
* @method getImage
* @param {String} id The id.
* @return {ia.Image} The image.
*/
ia.Report.prototype.getImage = function(id) {return this._imageHash[id];};
/**
* Builds a set of widgets based on the passed config object.
*
* @method build
* @param {Function} callbackFnc Function called when build is complete.
*/
ia.Report.prototype.build = function(callbackFnc)
{
this.removeWidgets();
// Devious method which allows us to use css to set the highlight and selection colors in the css.
// Placed here because it gives css time to load.
var highlightContainer = $j('<div class="ia-highlight-color ia-map-highlight-opacity">');
this.container.append(highlightContainer);
var selectionContainer = $j('<div class="ia-selection-color ia-map-selection-opacity">');
this.container.append(selectionContainer);
this.highlightColor = ia.Color.toHex(highlightContainer.css("color"));
this.selectionColor = ia.Color.toHex(selectionContainer.css("color"));
this.highlightOpacity = highlightContainer.css("opacity");
this.selectionOpacity = selectionContainer.css("opacity");
highlightContainer.remove();
selectionContainer.remove();
var widgetConfigs = this.config.getWidgets();
// Add this temporarily so all panels can pick up the panel border radius.
var tempPanelContainer = $j('<div class="ia-panel">');
this.container.append(tempPanelContainer);
for (var i = 0; i < widgetConfigs.length; i++)
{
var c = widgetConfigs[i];
var widget;
if (c.type === "component" || c.type === "table")
{
widget = new ia.Panel(c.id);
this.addPanel(widget);
}
else if (c.type === "button")
{
widget = new ia.Button(c.id);
this.addButton(widget);
}
else if (c.type === "text")
{
widget = new ia.Text(c.id);
this.addText(widget);
}
else if ((c.type === "image") || (c.type === "img")) // IE9 converts 'image' to 'img' when local.
{
widget = new ia.Image(c.id, c.src);
this.addImage(widget);
}
if (c.id.indexOf("filterButton") !== -1 || c.id.indexOf("geographyButton") !== -1)
widget.container.css("visibility","hidden"); // Hide filter and geog button unless needed.
else
widget.visible(c.visible);
widget.update(c);
}
tempPanelContainer.remove();
// Call back function.
if (callbackFnc != null) callbackFnc.call(null, this);
};
/**
* Updates dynamic text of widgets.
*
* @method updateDynamicText
* @param {ia.TextSubstitution} textSubstitution The TextSubstitution object.
*/
ia.Report.prototype.updateDynamicText = function(textSubstitution)
{
// Panel titles.
var configs = this.config.getComponents();
for (var i = 0; i < configs.length; i++)
{
var c = configs[i];
var s = textSubstitution.formatMessage(c.getProperty('title'));
this.getWidget(c.id).title(s);
}
// Text and Buttons.
var configs = this.config.getTexts().concat(this.config.getButtons());
for (var i = 0; i < configs.length; i++)
{
var c = configs[i];
var s = textSubstitution.formatMessage(c.text);
this.getWidget(c.id).text(s);
}
// TODO Column Headings.
};
/**
* Starts the progress bar.
*
* @method startProgress
* @param {String} id The id of the progress bar.
* @param {Function} callbackFnc The callbackFnc gets called once the progress container is ready.
*/
ia.Report.prototype._progressIds = [];
ia.Report.prototype.startProgress = function(id, callbackFnc)
{
this._progressIds[this._progressIds] = id;
this.$progressContainer.css("display", "inline");
ia.showWaitCursor();
// Need a delay to allow progress container to appear.
setTimeout(function() {callbackFnc.call(null);}, 100);
};
/**
* Ends the progress bar.
*
* @method endProgress
* @param {String} id The id of the progress bar.
*/
ia.Report.prototype.endProgress = function(id)
{
var index = this._progressIds.indexOf(id);
if (index !== -1) this._progressIds.splice(index, 1);
if (this._progressIds.length === 0)
{
this.$progressContainer.css("display", "none");
ia.showDefaultCursor();
}
};
/**
* Bloacks report interaction.
*
* @method startProgress
* @param {String} id The id of the interaction blocker.
* @param {Boolean} showWaitCursor Should wait cursor be displayed.
* @param {Function} callbackFnc The callbackFnc gets called once the progress container is ready.
*/
ia.Report.prototype._blockIds = [];
ia.Report.prototype.blockInteraction = function(id, showWaitCursor, callbackFnc)
{
this._blockIds[this._blockIds] = id;
this.$busyContainer.css("display", "inline");
if (showWaitCursor) ia.showWaitCursor();
// Need a delay to allow progress container to appear.
setTimeout(function() {callbackFnc.call(null);}, 100);
};
/**
* Allows report interaction.
*
* @method endProgress
* @param {String} id The id of the interaction blocker.
*/
ia.Report.prototype.allowInteraction = function(id)
{
var index = this._blockIds.indexOf(id);
if (index !== -1) this._blockIds.splice(index, 1);
if (this._blockIds.length === 0)
{
this.$busyContainer.css("display", "none");
ia.showDefaultCursor();
}
};
/**
* Displays the evaluation message.
*
* @method displayEvaluationMessage
* @param {ia.Panel} panel The panel to hold the message.
* @private
*/
ia.Report.prototype.displayEvaluationMessage = function(panel)
{
var evalMessage = "This report was prepared using an InstantAtlas™ evaluation license. It is not licensed for distribution or publication of any kind. For more information contact <a href='mailto:support@geowise.co.uk'>support@geowise.co.uk</a>, or visit <a href='http://www.instantatlas.com/' target='_blank'>http://www.instantatlas.com/</a>.";
var evalText = "Evaluation";
if (this.locale)
{
if (this.locale.getLanguage() === "de")
evalMessage = "Dieser Bericht wurde mit einer InstantAtlas™ Testlizenz erstellt. Er ist nicht zur Verbreitung oder Veröffentlichung jeglicher Art lizensiert. Für weitere Informationen kontaktieren Sie bitte <a href='mailto:support@geowise.co.uk'>support@geowise.co.uk</a> oder besuchen Sie <a href='http://www.instantatlas.com/de/' target='_blank'>http://www.instantatlas.com/</a>.";
else if (this.locale.getLanguage() === "fr")
evalMessage = "Ce rapport a été crée avec une licence d’évaluation. Cette licence ne permet pas la distribution ou la publication du rapport. Pour plus de renseignements veuillez contacter <a href='mailto:support@geowise.co.uk'>support@geowise.co.uk</a> ou consulter <a href='http://www.instantatlas.com/fr/' target='_blank'>http://www.instantatlas.com</a>.";
else if (this.locale.getLanguage() === "es")
{
evalMessage = "Este informe ha sido generado con una licencia de evaluación. La distribución o publicación del informe está prohibida. Para más información mande un email a <a href='mailto:support@geowise.co.uk'>support@geowise.co.uk</a> o consulte <a href='http://www.instantatlas.com/es/' target='_blank'>http://www.instantatlas.com</a>.";
evalText = "Evaluación";
}
}
var holder = $j("<div>");
holder.css({"position": "absolute",
"left":"5px",
"bottom":"5px",
"border-color":"#DCDCDC",
"border-width":"1px",
"border-style":"solid",
"background-color":"#f9f9f9",
"border-radius": "4px",
"padding":"5px",
"text-align": "right"});
var eval = $j("<div>").text(evalText)
eval.css({"font-family":"Arial Black", "font-size":"30px", "color":"#bbbbbb"});
var link = $j("<a href='http://www.instantatlas.com/' target='_blank'>").text("http://www.instantatlas.com");
if (this.locale)
{
if (this.locale.getLanguage() === "de") link = $j("<a href='http://www.instantatlas.com/de/' target='_blank'>").text("http://www.instantatlas.com");
else if (this.locale.getLanguage() === "fr") link = $j("<a href='http://www.instantatlas.com/fr/' target='_blank'>").text("http://www.instantatlas.com");
else if (this.locale.getLanguage() === "es") link = $j("<a href='http://www.instantatlas.com/es/' target='_blank'>").text("http://www.instantatlas.com");
}
link.css({"font-family":"Verdana", "font-size":"11px", "color":"#888888"});
var info = $j("<div>").html(evalMessage);
info.css({"position": "absolute",
"left":"30%",
"top":"40%",
"width":"40%",
"border-color":"#DCDCDC",
"border-width":"1px",
"border-style":"solid",
"background-color":"#f9f9f9",
"border-radius":"5px",
"padding":"10px",
"z-index":999999});
$j("body").bind(ia.CLICK_TYPE, function(e)
{
info.hide();
});
panel.append(holder)
holder.append(eval)
holder.append(link);
this.container.append(info);
};
/**
* Closes all popup windows except the one with the passed id.
*
* @method closePopups
* @param {String} id The popup id that should not be closed.
*/
ia.Report.prototype.closePopups = function(id)
{
var panels = this.getPanels();
for (var i = 0; i < panels.length; i++)
{
var panel = panels[i];
if (panel.popup() && panel.id !== id) panel.hide();
}
var callouts = this.getCallouts();
for (var i = 0; i < callouts.length; i++)
{
var callout = callouts[i];
if (callout.id !== id) callout.hide();
}
};