/*  share.js
This is the JS code used by the new share send and share received path pages
(see //depot/Web/Server/main/appserver/public_html/WEB-INF/jsp/app/share).
Nothing fancy here.  Just JS functions encapsulated as simple JS objects.
Of interest outside share might be the "ShareDialogMgr" object which provides
some nice UE enhancements to standard sflyDialogMgr dialogs (keyboard support).
*/
// utils.js uses below variables, else throws js error. These varaiables not used herein.
var userData = new Object();
var reqHttpPath = "";
var brandDir = "";
var uiDir = "";
var uiBase = "";
var sessionIsLogged = "0";
var sflylnk = 0;
/*
<sfly:javascriptInclude src="/incl_/utils.js" />
<sfly:javascriptInclude src="/incl_/shrpictures.js" />
*/
// Image selection object used by "album view," "detail view," and "all comments" pages.
var imageSelection = {
// class names for image states
_selected: "share-selected",
_active:   "share-active",
_current:  "share-current",
// Constants
_detailView: "detailView",
// Document elements of interest (set in imageSelection.init).
_selCount: null,
_dvImageNo: null,
_dvImage: null,
_dvImgSelected: null,
_dvGoToAlbumView: null,
_dvCommentCount: null,
_dvCommentDiv: null,
_dvCommentLink: null,
_dvDetailCommentCount: null,
// Comment list <div>s (for detail view)
_dvComments: null,
//share id, sid is stored
_sid:null,
// Event handler's arguments are <div> with class="share-item" and the
// picture index (0-based index within the album).  _onClick also takes
// a shiftKey boolean indicating whether the shift key was depressed.
_lastSelected: -1,
_onClick: function(ignored, n, shiftKey) {
// This click isn't deferred any longer.
this._deferredOnClick = null;
// Selecting or deselecting?
var newState = !this._selectedArray[n];
// Test for shift key.
var shiftClick = false;
if (shiftKey && this._lastSelected != -1) {
shiftClick = true;
// Shift-click *always* selects the element!
newState = true;
// Shift-click *always* de-selects items outside range.
this._selectAllOrNone(false, true);
} else {
// Pretend this one was last; makes the logic simpler.
this._lastSelected = n;
}
// Select/deselect the range from _lastSelected to n.
var first, last;
if (this._lastSelected < n) {
first = this._lastSelected;
last = n;
} else {
first = n;
last = this._lastSelected;
}
for (var i = first; i <= last; i++) {
// State changing?
if (newState != this._selectedArray[i]) {
// Tweak the DOM if pictures is visible.
if (i >= this._startIndex && i < this._startIndex + this._pageSize) {
try {dojo.toggleClass(this._items[i - this._startIndex], this._selected);} catch(e) {}
}
// Update "n items selected" message.
this._adjustCount(newState ? 1 : -1);
// Toggle value in array.
this._selectedArray[i] = newState;
}
}
// Remember this was the last one selected/deselected.  Shift-click doesn't move
// this anchor, however.
if (!shiftClick) {
this._lastSelected = n;
}
// Update cookie.
this._updateCookie();
return false;
},
_deferredOnClick: null,
clickDelay: 200,
_cancelPendingOnClick: function() {
if (this._deferredOnClick) {
window.clearTimeout(this._deferredOnClick);
this._deferredOnClick = null;
}
},
onClick: function(item, n, e) {
// Ignore previous click if we haven't handled it yet.
this._cancelPendingOnClick();
// Defer acting in case a double-click comes.
var evt = e || window.event || {shiftKey: false};
this._deferredOnClick = window.setTimeout("imageSelection._onClick(null, " + n + ", " + evt.shiftKey + ")", this.clickDelay);
return false;
},
_currentIndex: null,
viewIdArray: [],
// Returns the viewId of the current image
currentViewId: function() {
var viewId = null;
if (this._currentIndex != null && this._currentIndex < this.viewIdArray.length) {
viewId = this.viewIdArray[this._currentIndex];
}
return viewId;
},
getSelectedViewIds: function() {
var viewIds = [];
for (var i = 0; i < this._selectedArray.length; i++) {
if (this._selectedArray[i]) {
viewIds.push(this.viewIdArray[i]);
}
}
return viewIds;
},
onShowImage: function(ignored, n) {
// Handle going past either end.
if (n < 0) n = this._imageCount - 1;
else if (n == this._imageCount) n = 0;
// Mark item in DOM.
dojo.addClass(this._items[n], this._current);
// If not the initial image (which will have done this in the .jsp)...
if (this._currentIndex != null) {
// Un-mark the previously current image.
if (this._currentIndex != n) {
dojo.removeClass(this._items[this._currentIndex], this._current);
}
// Update the bg image src.
var src = dojo.query("DIV.share-item-num", this._items[n])[0].innerHTML;
this._dvImage.style.backgroundImage = "url(" + src + ")";
// Update the image title.
var title = dojo.query("DIV.share-item-title", this._items[n])[0].innerHTML;
var src = dojo.query(".share-detail DIV.share-title", document)[0].innerHTML = title;
// Update the image description.
var desc = dojo.query("DIV.share-item-desc", this._items[n])[0].innerHTML;
var src = dojo.query(".share-detail DIV.share-desc", document)[0].innerHTML = desc;
// Show the comments for this picture.
this._dvComments[this._currentIndex].style.display = 'none';
var comments = this._dvComments[n];
comments.style.display = '';
var count = parseInt(this._dvCommentCount.innerHTML = dojo.query("DIV.comment-item", comments).length);
// Show/hide the pseudo-comment depending on whether there are comments.
if (count == 0) {
// Show pseudo-comment.
dojo.addClass(this._dvCommentDiv, "share-noComments");
} else {
// Hide pseudo-comment.
dojo.removeClass(this._dvCommentDiv, "share-noComments");
}
// Update detail to show appropriate comment count.
dojo.removeClass(this._dvCommentLink, "share-none");
dojo.removeClass(this._dvCommentLink, "share-singular");
dojo.removeClass(this._dvCommentLink, "share-plural");
dojo.addClass(this._dvCommentLink, count == 0 ? "share-none" : (count == 1 ? "share-singular" : "share-plural"));
this._dvDetailCommentCount.innerHTML = count;
}
// Update image number in pagination area.
this._currentIndex = n;
this._dvImageNo.innerHTML = this._currentIndex + 1;
// Update "selected" checkbox.
this._dvImgSelected.checked = this._selectedArray[n];
// Scroll filmstrip so current image is visible.
var item = this._items[this._currentIndex].parentNode;
var grid = dojo.byId("share-grid");
var x = item.offsetLeft;
var cx = item.offsetWidth;
var px = grid.scrollLeft;
var pcx = grid.clientWidth;
if (x < px) {
// Scroll left so item shows.
grid.scrollLeft = x;
} else if (x + cx > px + pcx) {
// Scroll right so item shows.
grid.scrollLeft = x + cx - pcx;
}
// Update "album view" form to go to proper page.
// XXX We are cheating here; we don't really know that there are 16 pictures per page.
this._dvGoToAlbumView.startIndex.value = parseInt(this._currentIndex / 16) * 16;
return false;
},
prevImage: function() {
this.onShowImage(null, this._currentIndex - 1);
return false;
},
nextImage: function() {
this.onShowImage(null, this._currentIndex + 1);
return false;
},
_onDblClick: function(item, n, formId) {
// Cancel any pending onClick.
this._cancelPendingOnClick();
// Put selected index into form...
var form = document[formId || "gotoDetailView"];
form.imageIndex.value = n;
// ...and submit it.
form.submit();
return false;
},
onDblClick: function(item, n, formId) {
return this._onDblClick(item, n, formId);
},
onMouseOver: function(item, n) {
// Highlight item.
dojo.addClass(item, this._active);
return false;
},
onMouseOut: function(item, n) {
dojo.removeClass(item, this._active);
return false;
},
_ignoreDblClick: function(item, n) {
return false;
},
onSelect: function() {
var newState = !this._selectedArray[this._currentIndex];
this._selectedArray[this._currentIndex] = newState;
this._adjustCount(newState ? 1 : -1);
dojo.toggleClass(this._items[this._currentIndex], this._selected);
this._updateCookie();
},
_imageCount: null,
_selectedArray: null,
_startIndex: 0,
_pageSize: 0,
_view: null,
_imgData: null,
_initialized: false,
_pageLoaded: false,
init: function(imageCount, startIndex, pageSize, view, sid) {
this._imageCount = imageCount;
this._startIndex = parseInt(startIndex);
this._pageSize = parseInt(pageSize);
this._view = view;
this._sid=sid;
this._initialized = true;
// Page load complete (or not IE6)?
if (this._pageLoaded || dojo.isIE != 6) {
this._init();
}
},
// Initialization that has to wait till page load completes.
_init: function() {
this._imgData = new Cookie(document, "sflyImg", null, "/");
this._imgData.load();
//clear the cookie if sid are not same
this._validateCookie(this._sid);
this._selectedArray = new Array(this._imageCount);
this._selCount = dojo.byId("share-albumview-selCount") || {innerHTML: ""};
this._items = dojo.query("DIV.share-item", dojo.byId("share-grid"));
this._setSelectedPics();
if (this._view == "detailView") {
this._dvImageNo = dojo.byId("share-detailview-imageNumber");
this._dvImgSelected = dojo.byId("share-detailview-selected");
this._dvImage = dojo.byId("share-detailview-imgFrame");
this._dvGoToAlbumView = dojo.byId("share-gotoAlbumView");
this._dvCommentCount = dojo.byId("share-detailView-commentcount");
this._dvCommentDiv = this._dvCommentCount.parentNode;
while (this._dvCommentDiv.parentNode && !dojo.hasClass(this._dvCommentDiv, "share-comments")) {
this._dvCommentDiv = this._dvCommentDiv.parentNode;
}
this._dvCommentLink = dojo.query("SPAN.share-commentLink", document)[0];
this._dvDetailCommentCount = dojo.query("SPAN.share-commentCount", this._dvCommentLink)[0];
// Get comment list <div>s
this._dvComments = dojo.query("DIV.commentList", document);
// Adjust event handlers.
this._onClick = this.onShowImage;
this._onDblClick = this._ignoreDblClick;
// Kick off thumbnail loading.
window.setTimeout(dojo.hitch(imageSelection, "_setThumbnail", 0), 2000);
}
},
_onLoad: function() {
this._pageLoaded = true;
// Initialized (and IE6)?
if (this._initialized && dojo.isIE == 6) {
// Complete initialization with post-page-load portion.
this._init();
}
},
_setThumbnail: function(n) {
// Reached the end?
if (n >= this._imageCount) {
// Then we're done.
window.status = "";
return;
}
// Thumbnail not loaded already?
var img = dojo.query("IMG", this._items[n])[0];
if (!img.style.backgroundImage) {
img.style.backgroundImage = "url(" + this.thumbnailUrls[n] + ")";
}
// Load the next one.
if (!dojo.isIE || dojo.isIE < 7) {
window.status= this.properties["share.detailView.loading.text"];
}
window.setTimeout(dojo.hitch(imageSelection, "_setThumbnail", n + 1), 10);
},
openSlideshow: function(sid) {
// Slideshow page requires these JS objects.
window.slide = {
pics: [],
sid: sid,
orderAction: dojo.byId("order-form").getAttribute("action"),
saveAction: dojo.byId("save-form").getAttribute("action"),
lookup: function(id) {
var result = -1;
dojo.every(this.pics, function(pic, i) {
if (pic.url == id) {
result = i;
// Update selected state in case it changed.
pic.checked = imageSelection._selectedArray[i];
}
return result == -1;
});
return result;
},
placeOrder: function(win, cid) {
dojo.byId("order-form").cid.value = cid;
imageSelection.orderPrints(dojo.byId("order-form"));
},
_end: null
};
// Build pics array.
dojo.forEach(this.combIdArray, function(combId, i) {
window.slide.pics.push({'url': combId, 'viewId': this.viewIdArray[i], 'checked': this._selectedArray[i]});
}, this);
window.handler = {
updateOrder: function(slide, pid) {
var i = window.slide.lookup(pid);
if (i != -1) {
// Do selection the same way the page normally would.
if (imageSelection._view == "detailView") {
var save = imageSelection._currentIndex;
imageSelection._currentIndex = i;
imageSelection.onSelect();
imageSelection._currentIndex = save;
// Update checkbox if that's the current picture.
if (i == save) {
dojo.byId("share-detailview-selected").checked = !dojo.byId("share-detailview-selected").checked;
}
} else {
imageSelection._onClick(null, i);
}
}
},
_end: null
};
// Open full screen (Flash) slideshow in new window.
var screenheight = screen.availHeight - 80;
var screenwidth = screen.availWidth - 10;
flashSlideshowWindow = window.open('/view/flashShareSlideshow.jsp?sid='+sid, 'flashSlideshow','width='+screenwidth+',height='+screenheight);
flashSlideshowWindow.focus();
},
_onSelectionChange: null,
setOnSelectionChange: function(fn) {
// fn is a function taking as arguments a number and a flag indicating whether the
// number is absolute (versus a delta).
this._onSelectionChange = fn;
},
_selectAllOrNone: function(all, leaveLastSelectedAlone) {
var changed = false;
this._adjustCount(all ? this._selectedArray.length : 0, true);
// Update page, first.
var addOrRemove = all ? "addClass" : "removeClass";
// Now update array.
for (var i = 0; i < this._selectedArray.length; i++) {
if (this._selectedArray[i] != all) {
// On this page?
if (i < this._startIndex + this._pageSize && i >= this._startIndex) {
dojo[addOrRemove](this._items[i - this._startIndex], this._selected);
}
// Mark it as selected/unselected.
this._selectedArray[i] = all;
changed = true;
}
}
// Update "last selected"?
if (!leaveLastSelectedAlone) {
changed = changed || this._lastSelected != -1;
this._lastSelected = -1;
}
// Update cookie if something has changed.
if (changed) {
this._updateCookie();
}
},
selectAll: function() {
this._selectAllOrNone(true);
},
selectNone: function() {
this._selectAllOrNone(false);
},
setImgSrc: function(n, src) {
if (!this._imgSrc) {
this._imgSrc = new Array(this._imageCount);
}
this._imgSrc[n] = src;
},
_adjustCount: function(n, absolute) {
if (this._selCount) {
var selected = (absolute ? 0 : parseInt(this._selCount.innerHTML)) + n;
this._selCount.innerHTML = selected.toString();
}
if (this._onSelectionChange) {
this._onSelectionChange(n, absolute);
}
},
_arrangePos: -1,
_setSelectedPics: function() {
// Clear current selection array
for (var i=0 ; i < this._selectedArray.length ; i++) this._selectedArray[i] = false;
// Process cookie imgData
if (this._imgData.selected) {
// Use previous selection unmodified.
var selectedPics = this._imgData.selected.split(".") || [];
// Did we just rearrange?
if (this._rearranged && this._imgData._ap != undefined && this._imgData._ap != -1) {
// Position of where selected pictures were moved to were stored in the cookie.
var pos = parseInt(this._imgData._ap);
var n = selectedPics.length;
selectedPics = [];
for (var i = pos; i < pos + n; i++) {
selectedPics.push(i);
}
}
// Set selection count.
this._adjustCount(selectedPics.length, true);
// Process selected pictures...
for (var i = 0; i < selectedPics.length; i++) {
var imageIndex = parseInt(selectedPics[i]);
if ( imageIndex >= this._imageCount ) {
continue;
}
// Mark it selected.
this._selectedArray[imageIndex] = true;
// If on this page, "select" corresponding <div>.
if (imageIndex >= this._startIndex && imageIndex < this._startIndex + this._pageSize) {
try {dojo.addClass(this._items[imageIndex - this._startIndex], this._selected);} catch(e) {}
}
}
}
// Process saved "last selected" value.
if (this._imgData._ls) {
this._lastSelected = parseInt(this._imgData._ls);
}
// Clear "rearrange".
if (this._rearranged) {
this._arrangePos = -1;
this._updateCookie();
}
},
//remove cookie date if sid not equal to sid in cookie
_validateCookie: function(sid) {
if ((!sid) || (sid != this._imgData.sid)) {
this._imgData.remove();
this._imgData.selected ="";
this._imgData.sid = "";
this._imgData.store();
}
},
_updateCookie: function() {
var selected = [];
for (var i = 0; i < this._selectedArray.length; i++) {
if (this._selectedArray[i]) selected.push(i);
}
this._imgData.selected = selected.join(".");
this._imgData.sid = this._sid;
this._imgData._ls = this._lastSelected;
this._imgData._ap = this._arrangePos;
this._imgData.store();
},
_savedForm: null,
orderPrints: function(form, currentViewId) {
// Save form for later (if provided).
this._savedForm = form || this._savedForm;
var viewIds = this.getSelectedViewIds();
if (viewIds.length == 0) {
if (currentViewId == null) {
// No pictures selected, ask user if they want all.
orderPrintsDialog.show();
return;
}
else {
viewIds.push(currentViewId);
}
}
this._savedForm.selectedItems.value = viewIds.join(",");
this._savedForm.submit();
},
savePictures: function(form) {
// Save form for later (if provided).
this._savedForm = form || this._savedForm;
var viewIds = this.getSelectedViewIds();
if (viewIds.length == 0) {
// No pictures selected, ask user if they want all.
savePicturesDialog.show();
return;
}
this._savedForm.selectedItems.value = viewIds.join(",");
if (dojo.isIE == 6) {
// "object doesn't support this property or method" snafu workaround
this._submit(this._savedForm);
} else {
this._savedForm.submit();
}
},
createProduct: function(form) {
// Ignore if somehow "-- choose product --" was selected.
if (!form.projectType.value) {
return;
}
// Determine whether selected product is multi-image, and, get product type
var productType = "";
var multiImg = true;
dojo.some(dojo.query("OPTION", form.projectType), function(opt) {
var done = false;
if (opt.value == form.projectType.value) {
done = true;
productType = opt.innerHTML.toLowerCase();
multiImg = dojo.hasClass(opt, "share-multi");
}
return done;
});
// Get alternate text for use in dialogs for this product; defaults to dropdown text.
productType = this.properties["share.create.dialog." + form.projectType.value] || productType;
// Get selected viewIds
var viewIds = this.getSelectedViewIds();
// Put in form.
form.selectedItems.value = viewIds.join(",");
// These specify the dialog to show.
var dialogParams = { type: "confirm",
name: "", // title/content derived from this
icon: "question",
cancelCallback: dojo.hitch(this, "_cancelCallback", form) };
if (multiImg) {
// Multi-image product...
if (viewIds.length == 0) {
// 1 Show "Select and use all pictures?" confirmation dialog and do that if Ok.
dialogParams.name = "useall";
dialogParams.okCallback = dojo.hitch(this, "_selectAllAndSubmitForm", form);
} else {
// 2 Show "Use <n> selected pictures?" confirmation dialog and continue if Ok.
dialogParams.name = "useselected";
dialogParams.okCallback = dojo.hitch(this, "_submit", form);
}
} else {
// Single-image product...
if (viewIds.length == 0) {
if (this._view == "detailView") {
if (this._imageCount == 1) {
// 3a Proceed with the single image.
dialogParams.okCallback = dojo.hitch(this, "_submitFormUsingSingleImage", form, this.viewIdArray[0]);
} else {
// 3b Proceed with the current image.
dialogParams.okCallback = dojo.hitch(this, "_submitFormUsingSingleImage", form, this.viewIdArray[this._currentIndex]);
}
} else {
// Only one image in album?
if (this._imageCount == 1) {
// 4 Show "Use the only picture?" confirmation dialog and do so if Ok.
dialogParams.okCallback = dojo.hitch(this, "_submitFormUsingSingleImage", form, this.viewIdArray[0]);
} else {
// 5 Show "Choose one picture" alert.
dialogParams.type = "alert";
dialogParams.icon = "warning";
dialogParams.name = "selectone";
// Clear selection.
this._cancelCallback(form);
}
}
} else if (viewIds.length == 1) {
if (this._view == "detailView") {
// Is selected one not the current one?
if (!this._selectedArray[this._currentIndex]) {
// 6 Show "Use selected/other picture?" confirmation and continue if Ok.
dialogParams.name = "useother";
// "Yes" means use the current picture. "No" means use the selected picture instead.
// Which is selected is discerned by _submitFormUsingSingleImage.
dialogParams.content  = "<div id='share-useother-text-1'>" +
this.properties["share.create.useother.confirm.text.1"] +
"</div>";
dialogParams.content += "<form id='share-useother'>" +
"<input name='share-useother-viewId' id='share-useother-current'  tabindex='1' type='radio' value='" + this.viewIdArray[this._currentIndex] + "' checked />" +
"<label for='share-useother-current'>" + this.properties["share.create.useother.confirm.label.current"] + "</label><br/>" +
"<input name='share-useother-viewId' id='share-useother-selected' tabindex='2' type='radio' value='" + viewIds[0] + "' />" +
"<label for='share-useother-selected'>" + this.properties["share.create.useother.confirm.label.selected"] + "</label>" +
"</form>";
dialogParams.content += "<div id='share-createProduct-text2'>" +
this.properties["share.create.useother.confirm.text.2"] +
"</div>";
dialogParams.okCallback = dojo.hitch(this, "_submitFormUsingSingleImage", form, null);
dialogParams.width = "425";
dialogParams.focus = "share-useother-current";
} else {
// 7a Create product using current/selected picture.
dialogParams.okCallback = dojo.hitch(this, "_submit", form);
}
} else {
// 7b Create product using selected picture.
dialogParams.okCallback = dojo.hitch(this, "_submit", form);
}
} else {
// Too many selected...
if (this._view == "detailView") {
// Is the current picture one of the selected ones?
if (this._selectedArray[this._currentIndex]) {
// 8 Show "Use current picture?" confirmation dialog and do so if Ok.
dialogParams.name = "useonlycurrent";
dialogParams.okCallback = dojo.hitch(this, "_submitFormUsingSingleImage", form, this.viewIdArray[this._currentIndex]);
} else {
// 9 Show "Select only one picture" alert and then go to album view.
dialogParams.type = "alert";
dialogParams.name = "selectonlyone";
dialogParams.okCallback = dojo.hitch(this, "_submit", dojo.byId("share-gotoAlbumView"));
}
} else {
// 10 Show "Choose one and try again" alert.
dialogParams.type = "alert";
dialogParams.name = "selectonlyone";
}
}
}
// Show dialog, if necessary.
if (dialogParams.name) {
// Derive tags for title and content from name+type.
var tagPrefix = "share.create." + dialogParams.name + "." + dialogParams.type + ".";
// Get title/content from properties.
var title   = this.properties[tagPrefix + "title"];
var content = this.properties[tagPrefix + "text"];
if (!content && !dialogParams.content) {
// Get parts 1 and 2.
var part1 = this.properties[tagPrefix + "text.1"];
var part2 = this.properties[tagPrefix + "text.2"];
content   = "<div id='share-createProduct-text1'>" +
part1 +
"</div>" +
"<div id='share-createProduct-text2'>" +
part2 +
"</div>";
}
// Replace parameters with product type and number of selected pictures.
dialogParams.title   = title.replace(/\{0\}/g, productType).replace(/\{1\}/g, viewIds.length);
// Note: dialogParams.content has already been defined for case 6 (see above).
dialogParams.content = (dialogParams.content || content).replace(/\{0\}/g, productType).replace(/\{1\}/g, viewIds.length);
// Show the dialog.
shareDialogMgr.showShareDialog(dialogParams);
} else {
// No dialog.  Perform action if specified in okCallback property.
if (dialogParams.okCallback) {
dialogParams.okCallback();
}
}
},
_cancelCallback: function(form) {
},
_form: null,
_submit: function(form) {
if (dojo.isIE) {
// IE won't submit the form directly.  Do it on a timeout.
this._form = form;
window.setTimeout("imageSelection._form.submit()", 100);
} else {
// Submit the form.
form.submit();
}
},
_selectAllAndSubmitForm: function(form) {
this.selectAll();
form.selectedItems.value = this.getSelectedViewIds().join(",");
if (dojo.isIE == 6) {
// IE6 "object doesn't support this property or method" snafu workaround.
this._submit(form);
} else {
form.submit();
}
},
_submitFormUsingSingleImage: function(form, viewId, dlgForms) {
// Need to get viewId from dialog?
if (!viewId) {
// Use the value of the checked radio button on the dialog.
if (dlgForms[0]["share-useother-current"].checked) {
viewId = dlgForms[0]["share-useother-current"].value;
} else {
viewId = dlgForms[0]["share-useother-selected"].value;
}
}
form.selectedItems.value = viewId;
this._submit(form);
},
rotateImages: function(form) {
var viewIds = this.getSelectedViewIds();
if (viewIds.length > 0) {
form.selectedItems.value = viewIds.join(",");
form.submit();
}
},
_end: null
}; // imageSelection
// Hook into page load.
dojo.addOnLoad(dojo.hitch(imageSelection, "_onLoad"));
// Used on "edit share" page; based on imageSelection object, above.
var shareEdit = {
_imageCount: null,
_pageSize: null,
_prevPageButtons: null,
_nextPageButtons: null,
_gotoPageSelects: null,
init: function(imageCount, pageSize) {
this._imageCount = parseInt(imageCount);
this._pageSize = parseInt(pageSize);
// Tell imageSelection that all the items are on the page!
imageSelection.init(imageCount, 0, imageCount, "shareEdit", "share-edit");
// Get pagination stuff.
this._prevPageButtons = dojo.query("FORM.share-prev-btn A", document);
this._nextPageButtons = dojo.query("FORM.share-next-btn A", document);
this._gotoPageSelects = dojo.query(".share-pagination SELECT", dojo.byId("share-images"));
// Show the first page.
this._show(0);
},
gotoPage: function(sel) {
// Show the specified page.
this._show(sel.parentNode.startIndex.value);
return false;
},
prevPage: function() {
this._show(this._startIndex - this._pageSize);
},
nextPage: function() {
this._show(this._startIndex + this._pageSize);
},
setPageSize: function(sel) {
var pageSize = parseInt(sel.parentNode.pageSize.value);
// Hide current page.
this._hide(this._startIndex);
// Calculate new start; keep current images visible.
var startIndex = parseInt(this._startIndex / pageSize) * pageSize;
// Rebuild pagination dropdown lists.
if (dojo.isIE) {
var opts = [];
for (var i = 0; i < this._imageCount; i += pageSize) {
opts.push({value: i, innerHTML: (i+1) + '&nbsp;-&nbsp;' + Math.min(i + pageSize, this._imageCount)});
}
dojo.forEach(this._gotoPageSelects, function(sel) {
sel.innerHTML = "";
dojo.forEach(opts, function(optInfo) {
var opt = document.createElement('OPTION');
opt.value = optInfo.value;
opt.innerHTML = optInfo.innerHTML;
sel.appendChild(opt);
});
});
} else {
var opts = "";
for (var i = 0; i < this._imageCount; i += pageSize) {
opts += '<option value="' + i + '">' + (i+1) + '&nbsp;-&nbsp;' + Math.min(i + pageSize, this._imageCount) + '</option>';
}
dojo.forEach(this._gotoPageSelects, function(sel) {
sel.innerHTML = opts;
});
}
// Show the new page.
this._startIndex = -1;
this._pageSize = pageSize;
this._show(startIndex);
// Store page size in cookie.
imageSelection._imgData._ps = this._pageSize;
imageSelection._updateCookie();
return false;
},
remove: function(form) {
// Put selected picture paths into form.
form.paths.value = imageSelection.getSelectedViewIds().join(",");
if (form.paths.value.length) {
form.submit();
} else {
// Show alternative instructions.
this._changeInstructions(true);
}
},
arrange: function() {
arrangePicturesDialog.show();
},
_startIndex: -1,
_show: function(startIndex) {
// Hide previous page.
if (this._startIndex != -1) {
this._hide(this._startIndex);
}
this._startIndex = parseInt(startIndex);
for (var i = this._startIndex; i < this._startIndex + this._pageSize && i < this._imageCount; i++) {
// Get thumbnail URL from where it was stashed.
var item = imageSelection._items[i];
var src = dojo.query("DIV.share-item-desc", item)[0].innerHTML;
dojo.query("IMG", item)[0].src = src;
// Show this image.
item.style.display = dojo.isIE < 7 ? 'inline' : 'block';
}
// Update pagination controls.
dojo.forEach(this._prevPageButtons, function (btn) {
dojo.removeClass(btn, "share-disabled");
btn.href = "#";
});
dojo.forEach(this._nextPageButtons, function (btn) {
dojo.removeClass(btn, "share-disabled");
btn.href = "#";
});
if (this._startIndex == 0) {
dojo.forEach(this._prevPageButtons, function (btn) {
dojo.addClass(btn, "share-disabled");
btn.removeAttribute("href");
});
}
if (this._startIndex + this._pageSize >= this._imageCount) {
dojo.forEach(this._nextPageButtons, function (btn) {
dojo.addClass(btn, "share-disabled");
btn.removeAttribute("href");
});
}
dojo.forEach(this._gotoPageSelects, function (sel) {
dojo.forEach(sel.getElementsByTagName("OPTION"), function (opt) {
opt.selected = opt.value == startIndex;
});
});
},
_hide: function(startIndex) {
for (var i = startIndex; i < startIndex + this._pageSize && i < this._imageCount; i++) {
var item = imageSelection._items[i];
item.style.display = '';
}
},
_instructions: null,
_noneSelected: "share-edit-noneSelected",
_changeInstructions: function(noneSelected) {
if (!this._instructions) {
this._instructions = dojo.byId("share-edit-select");
}
if (noneSelected) {
dojo.addClass(this._instructions, this._noneSelected);
// Watch for selection.
imageSelection.setOnSelectionChange(function(){shareEdit._changeInstructions(false);});
} else {
dojo.removeClass(this._instructions, this._noneSelected);
// Cancel selection watch.
imageSelection.setOnSelectionChange(null);
}
},
_end: null
}; // shareEdit
// Landing page...
var landingPage = {
_projectType: null,
_sid: null,
_frameId: null,
_service: null,
init: function(projectType, sid, frameId) {
this._sid = sid;
this._frameId = frameId;
this._projectType = projectType;
var controllerOpts = {};
controllerOpts.central = {};
controllerOpts.central.ajaxUrl = "/share/received/ajax.ajax";
controllerOpts.central.frameId = frameId;
this._service = new sfly.page.BasePageController(controllerOpts);
},
learnMore: function() {
shareDialogMgr.showShareDialog({type: "alert",
icon: "info",
title: this._getProperty("share.recd.project.save.learnmore.title"),
content: this._getProperty("share.recd.project.save.learnmore.text")});
},
saveProject: function(className) {
shareDialogMgr.showShareDialog({type: "confirm",
icon: (className && className.indexOf("share-error") != -1) ? "warning" : "question",
btnType: "save",
className: className,
focus: "projectTitle",
title: this._getProperty("share.recd.project.save.title"),
content: dojo.byId("share-recd-saveProject").innerHTML,
okCallback: dojo.hitch(this, "_saveProject")});
},
savePictures: function() {
shareDialogMgr.showShareDialog({type: "info",
title: this._getProperty("share.recd.project.savePics.title"),
content: this._getProperty("share.recd.project.savePics.text")});
var params = {
method: "saveProjectImages",
data: {sid: this._sid},
frameId: this._frameId,
callback: dojo.hitch(this, "_savePicturesComplete"),
service: "self"
};
this._service.requestServiceCall(params);
},
_form: null,
_submit: function(form) {
if (dojo.isIE) {
// IE won't submit the form directly.  Do it on a timeout.
this._form = form;
window.setTimeout("landingPage._form.submit()", 100);
} else {
// Submit the form.
form.submit();
}
},
orderProject: function(form) {
shareDialogMgr.showShareDialog({type: "confirm",
icon: "question",
btnType: "yes",
title: this._getProperty("share.orderProject.dlg.title"),
content: this._getProperty("share.orderProject.dlg.text"),
okCallback: dojo.hitch(this, "_submit", form),
cancelCallback: dojo.hitch(this, "_orderProject", form)});
},
_saveProject: function(forms) {
// Validate project name.
var className = "";
var name = dojo.trim(forms[0].projectTitle.value);
var baseForm = dojo.query("FORM", dojo.byId("share-recd-saveProject"))[0];
if (name.length == 0) {
var className = "share-error share-emptyName";
} else if (name.length > 80) {
var className = "share-error share-nameTooLong";
forms[0].projectTitle.value = baseForm.projectTitle.value = name.substring(0, 80);
baseForm.projectTitle.setAttribute("value", forms[0].projectTitle.value);
} else if (name.match(/[^\w|\s]/)) {
var className = "share-error share-invalidName";
forms[0].projectTitle.value = baseForm.projectTitle.value = name.replace(/[^\w|\s]/g, "");
baseForm.projectTitle.setAttribute("value", forms[0].projectTitle.value);
}
if (className.length) {
// Show error to user and try again.
this.saveProject(className);
} else {
shareDialogMgr.showShareDialog({type: "info",
title: this._getProperty("share.recd.project.save.saving.title"),
content: this._getProperty("share.recd.project.save.saving.text")});
var params = {
method: "saveProject",
data: {sid: this._sid, projectTitle: forms[0].projectTitle.value},
frameId: this._frameId,
callback: dojo.hitch(this, "_saveComplete"),
service: "self"
};
this._service.requestServiceCall(params);
}
},
_saveComplete: function(data) {
if (data.success) {
shareDialogMgr.showShareDialog({type: "alert",
icon: "info",
title: this._getProperty("share.recd.project.save.done.title"),
content: this._getProperty("share.recd.project.save.done.text", this._projectType, data.editURL)});
} else {
shareDialogMgr.showShareDialog({type: "alert",
icon: "warning",
title: this._getProperty("share.recd.project.save.failed.title"),
content: this._getProperty("share.recd.project.save.failed.text")});
}
},
_savePicturesComplete: function(data) {
if (data.success) {
shareDialogMgr.showShareDialog({type: "alert",
icon: "info",
title: this._getProperty("share.recd.project.savePics.done.title"),
content: this._getProperty("share.recd.project.savePics.done.text", this._projectType, data.refreshURL, data.editURL)});
} else {
shareDialogMgr.showShareDialog({type: "alert",
icon: "warning",
title: this._getProperty("share.recd.project.savePics.failed.title"),
content: this._getProperty("share.recd.project.savePics.failed.text")});
}
},
_orderProject: function(form) {
form.cid.value = form.orderCid.value;
form.action = form.orderAction.value;
if (dojo.isIE == 6) {
this._submit(form);
} else {
form.submit();
}
},
_getProperty: function(tag, type, url1, url2) {
var property = this.properties[tag] || tag;
property = property.replace(/\{0\}/g, type || this._projectType);
property = property.replace(/\{1\}/g, url1);
property = property.replace(/\{2\}/g, url2);
return property;
},
_end: null
}; // landingPage
// sharedVideo
var sharedVideo = {
_videoSourceId: null,
_videoSourceToken: null,
_videoData: null,
_player: null,
_links: null,
_videoHDStatus: null,
_pageLoaded: false,
_videoFormat: null,
_videoAspectRatio: null,
properties: {},
// Initialize; binds video to content on page; player and links are ids of <div> elements
init: function(id, token, premiumMember, playerId, linksId) {
this._videoSourceId    = id;
this._videoSourceToken = token;
this._premiumMember = premiumMember;
this._player = playerId;
this._links  = linksId;
// Kick things off by showing "sd" video.
this._renderPlayer("sd");
},
_renderPlayer: function(fmt) {
// Load motionbox code.
dojo.registerModulePath("motionbox", "../../motionbox");
//dojo.require("motionbox.MBXHaClient");
// closure for callbacks
var self = this;
// Wait until page load completes...
if (!this._pageLoaded) {
dojo.addOnLoad(function() {
self._pageLoaded = true;
// Now we can access player and links content.
self._player = dojo.byId(self._player);
self._links  = dojo.byId(self._links);
// Now show the video in requested format ("sd").
self._renderPlayer(fmt);
});
return;
}
if (dojo.isIE && !this._pageLoaded) {
// IE sux
return;
}
if (!this._videoData) {
// Get metadata from motionbox
MBX.Video.find(this._videoSourceId, this._videoSourceToken, function(videoData) {
// Store video metadata.
self._videoData = videoData;
// Render links.
self._renderLinks(videoData);
// Now (re)render the player.
self._renderPlayer(fmt);
});
if ((fmt || "sd") != "sd") {
// Can't render non-sd until we get metadata.
return;
}
} else if (fmt == "hd") {
// Ensure hd encoding available.
var hdStatus = this._getHDVideoStatus();
if (hdStatus != "playable") {
if (hdStatus == "available_for_encoding") {
// Request HD encoding.
this._setHDVideoStatus("encoding");
// In queue?
if (!this._videoData.formats.hd.encodingProgress) {
}
MBX.Video.encode(this._videoSourceId, this._videoSourceToken, fmt, function(format) {
self._videoData.formats.hd = format;
// Try again; status is presumably "encoding" so this will trigger an encodingProgress call.
self._renderPlayer(fmt);
});
// Update progress after delay.
this._videoData.formats.hd.status = "encoding";
this._renderPlayer(fmt);
} else if (hdStatus == "encoding") {
// Update status on screen.
dojo.byId("videoHDEncodingProgress").innerHTML = this._videoData.formats.hd.encodingProgress || 0;
// Check status in five seconds.
window.setTimeout(dojo.hitch(this, self._encodingProgress, fmt), 5000);
}
// Wait for encoding to complete.
return;
} else {
this._setHDVideoStatus("playable");
}
}
// Get aspect ratio.
var aspectRatio = this._getVideoAspectRatio(fmt);
// Rendering different content than we already have?
if ((fmt || "sd") != this._videoFormat || aspectRatio != this._videoAspectRatio) {
// (Re)render the video.
var w = (fmt == "hd") ? 960 : 640;
var h = parseInt(w * aspectRatio + 0.5);
this._videoFormat = fmt || "sd";
this._videoAspectRatio = aspectRatio;
var player = MBX.Player.embedFor(this._videoSourceId, this._videoSourceToken, this._videoFormat, {width: w, height: h, wmode: "transparent"});
this._player.innerHTML = player;
if (fmt == "hd") {
dojo.addClass(dojo.body(), "share-video");
dojo.addClass(dojo.body(), "share-hdVideo");
// Add 38px (2 for border, 18 for padding, plus 18 top margin); except on IE6
if (dojo.isIE != 6) {
dojo.byId("videoSpacer").style.height = (h + 38) + "px";
}
this._setHDVideoStatus("playing");
} else {
dojo.addClass(dojo.body(), "share-video");
dojo.removeClass(dojo.body(), "share-hdVideo");
if (dojo.byId("videoSpacer")) {
dojo.byId("videoSpacer").style.height = 0;
}
this._setHDVideoStatus(this._getHDVideoStatus());
}
}
},
// Renders content of "links" <div>; requires video metadata
_renderLinks: function(videoData) {
if (this._links) {
// Start with vertical spacer.  This will always be the size of the player <div> if in hd/hq mode.
var links = "<div id='videoSpacer'></div>";
// HQ or HD?
var hd = this._getVideoQuality(videoData);
if (this._premiumMember && hd) {
// Add "view in hq/hd" link.
links += "<a href='#hd' id='videoHD' class='disabled' onclick='return sharedVideo._onHDLinkClick()'>";
// 3 flavors of text (depending on status).
links += this._renderOption(hd, "normal");
links += this._renderOption(hd, "encoding");
links += this._renderOption(hd, "alreadyPlaying");
links += "</a>";
// Add "download" link
links += "<a href='#download' id='videoDL' onclick='return sharedVideo._onDLLinkClick()'>";
links += this._getProperty("share.recd.video.action.DL.link");
links += "</a>";
}
dojo.byId(this._links).innerHTML = links;
}
},
_renderOption: function(quality, state) {
var opt = "<span id='videoHD-" + state + "'>" + this._getProperty("share.recd.video.action." + quality + ".link." + state) + "</span>";
return opt;
},
_getProperty: function(key) {
return this.properties[key] || "???" + key + "???";
},
_onHDLinkClick: function() {
var className = this._hdVideoStatus && this._hdVideoStatus.className;
if (className == "encoding") {
// Ignore click
} else {
// Show sd if hd playing, else show hd.
this._renderPlayer(className == "playing" ? "sd" : "hd");
}
return false;
},
_onDLLinkClick: function() {
if (this._videoData && this._videoFormat && this._videoData.formats && this._videoData.formats[this._videoFormat]) {
var format = this._videoData.formats[this._videoFormat];
if (format.downloadUrl) {
window.location.href = this._videoData.formats[this._videoFormat].downloadUrl;
}
}
return false;
},
_getHDVideoStatus: function() {
// Presume "available_for_encoding" if we haven't got the metadata yet.
return (this._videoData && this._videoData.formats && this._videoData.formats.hd && this._videoData.formats.hd.status) || "available_for_encoding";
},
_hdVideoStatus: null,
_setHDVideoStatus: function(status) {
this._hdVideoStatus = this._hdVideoStatus || dojo.byId("videoHD");
if (this._hdVideoStatus) {
this._hdVideoStatus.className = status;
}
},
// returns video quality; "" if neither HQ nor HD (no HD/HQ link)
_getVideoQuality: function() {
var h = (this._videoData && this._videoData.sourceHeight) || 240;
if (h < 240) {
return "";
} else if (h >= 240 && h < 720) {
return "HQ";
} else {
return "HD";
}   
},
_getVideoAspectRatio: function(fmt) {
var aspectRatio = 9/16;
if (this._videoData) {
var format = this._videoData.formats[fmt || "sd"];
if (format) {
aspectRatio = format.height / format.width;
// Canonicalize to either 16x9 or 4x3
if (aspectRatio >= 1.7 && aspectRatio <= 1.8) {
aspectRatio = 9/16;
} else {
aspectRatio = 3/4;
}
}
}
return aspectRatio;
},
_encodingProgress: function(fmt) {
var self = this; // closure
var ep = MBX.Video.encodingProgress([{uid: this._videoSourceId, securityToken: this._videoSourceToken}], function(response) {
response = response[self._videoSourceId];
if (!response || !response.hd) {
// This shouldn't happen.
return;
}
// Update status.
self._videoData.formats.hd.status   = response.hd.status;
self._videoData.formats.hd.encodingProgress = response.hd.encodingProgress;
// Try again.
self._renderPlayer(fmt);
});
},
_end: null// sharedVideo
};
// "overflow page" code called on "remove/delete" to display confirmation
// dialog.  This is very similar to code on the shareTab page and on the
// album view page.  Maybe we can merge them someday.
var overflowPage = {
_callback: {
_form: null,
onOk: function() {
this._form.submit();
},
_end: null
},
confirmDelete: function(sid, sentOrRecd, type) {
// Put values in form.
this._callback._form = dojo.byId("share-form-delete");
this._callback._form.id.value = sid;
this._callback._form.type.value = sentOrRecd;
this._callback._form.fromPage.value = sentOrRecd == "SEND" ? 1 : 2;
// Ask user for confirmation.
shareDialogMgr.showShareDialog({        type: "confirm"
,   btnType: "yes"
,   icon: "warning"
,   title: this.properties[this["_titleTag" + sentOrRecd]]
,   content: this.properties[this["_contentTag" + sentOrRecd]]
,   okCallback: dojo.hitch(this._callback, "onOk")});
return false;
},
_titleTagRECEIVED: "share.sharetab.removeshare.title",
_contentTagRECEIVED: "share.sharetab.removeshare.content",
_titleTagSEND: "share.sharetab.deleteshare.title",
_contentTagSEND: "share.sharetab.deleteshare.content",
_end: null
}; // overflowPage
// Extend sflyDialogMgr to make dialogs keyboard friendly.
var shareDialogMgr = {
// Note: This function doesn't support the second "caller" argument that
//       sflyDialogMgr.showSflyDialog does.  Simply use dojo.hitch to
//       bind your okCallback/cancelCallback properties to objects.
showShareDialog: function(dialogParams) {
// Ensure dialogs are tweaked.
this._init(dialogParams);
if (window.sflyDialogMgr) {
// Intercept okCallback so we can provide form data.
if (dialogParams.okCallback) {
dialogParams.okCallback = dojo.hitch(this, "_okCallback", dialogParams.type, dialogParams.okCallback);
}
// Show the dialog.
sflyDialogMgr.showSflyDialog(dialogParams);
// Set initial focus (on timeout, to allow dialog to come to life first).
var focus = dialogParams.focus || dialogParams.type + "DialogContainer-okBtnImg";
window.setTimeout("shareDialogMgr._focus('" + dialogParams.type + "', '" + focus + "', " + (dialogParams.className ? ("'" + dialogParams.className + "'") : null ) + ")", 100);
}
},
_focus: function(type, name, className) {
// Set focus to element with given name (or id)
var elem = dojo.byId(name);
if (!elem) {
// Look for form field with given name.
dojo.forEach(dojo.query("FORM", dojo.byId(type + "DialogContainer-content")), function(form) {
if (form[name]) {
elem = form[name];
}
});
}
if (elem) {
// If IE and elem is an IMG, try focusing its parent
// (the <A> we inserted, most likely), instead.
(dojo.isIE && elem.tagName == "IMG" ? elem.parentNode : elem).focus();
}
// If className specified, apply it now.
if (className && className.length) {
this._dialogs[type]._content.className = this._dialogs[type]._contentClass;
dojo.addClass(this._dialogs[type]._content, className);
}
},
_okCallback: function(type, userCallback) {
var forms = [];
dojo.forEach(dojo.query("FORM", this._dialogs[type]._content), function(form) {
forms.push(form);
});
userCallback(forms);
},
_dialogs: {},
_init: function(dialogParams) {
if (!this._dialogs[dialogParams.type] && window.sflyDialogMgr) {
// Initialize this type of dialog.
var dlg       = dojo.byId(sflyDialogMgr.dialogs[dialogParams.type + "Dialog"]);
var content   = dojo.byId(dialogParams.type + "DialogContainer-content");
var okBtn     = dojo.byId(dialogParams.type + "DialogContainer-okBtnImg");
var cancelBtn = dojo.byId(dialogParams.type + "DialogContainer-cancelBtnImg");
// IE doesn't like giving focus to <img>s.  Wrap those with <A>s.
if (dojo.isIE) {
if (okBtn) {
okBtn = okBtn.parentNode.insertBefore(document.createElement("A"), okBtn);
okBtn.appendChild(okBtn.parentNode.removeChild(okBtn.nextSibling));
okBtn.href = "javascript:undefined";
}
if (cancelBtn) {
cancelBtn = cancelBtn.parentNode.insertBefore(document.createElement("A"), cancelBtn);
cancelBtn.appendChild(cancelBtn.parentNode.removeChild(cancelBtn.nextSibling))
cancelBtn.href = "javascript:undefined";
}
}
this._dialogs[dialogParams.type] = {_okBtn: okBtn, _cancelBtn: cancelBtn, _dlg: dlg, _content: content, _contentClass: content.className };
// Fix the buttons.
if (okBtn) {
okBtn.setAttribute("tabindex", 100);
okBtn.onkeyup = dojo.hitch(this, "_onKeyup", dlg, "invokeOkCallback");
okBtn.onfocus = dojo.hitch(dlg, "okRollover");
okBtn.onblur  = dojo.hitch(dlg, "okRollout");
}
if (cancelBtn) {
cancelBtn.setAttribute("tabindex", 101);
cancelBtn.onkeyup = dojo.hitch(this, "_onKeyup", dlg, "invokeCancelCallback");
cancelBtn.onfocus = dojo.hitch(dlg, "cancelRollover");
cancelBtn.onblur  = dojo.hitch(dlg, "cancelRollout");
}
}
},
// You can call this to cause the Enter key in a given form field to submit the form.
// Simply add: onkeyup="shareDialog.onKeyup(this, event)" to the <input> field.
_keyCache: {},
onKeyup: function(input, e) {
// Check cache.
if (this._keyCache._name != input.name) {
// Flush cache.
this._keyCache = {};
// Walk up the parent chain until we find the dialog content node.
var content = input.form.parentNode;
while (content && content.id.indexOf("DialogContainer-content") == -1) {
content = content.parentNode;
}
if (content) {
// Get dialog type.
var type = content.id.substr(0, content.id.indexOf("DialogContainer-content"));
// Get corresponding dialog widget.
var dlg = this._dialogs[type]._dlg;
// Put that in the cache.
this._keyCache._name = input.name;
this._keyCache._dlg  = dlg;
}
}
// Did we find the dialog widget?
if (this._keyCache._dlg) {
// Invoke it's okCallback handler.
this._onKeyup(this._keyCache._dlg, "invokeOkCallback", e);
}
},
// This is used internally to handle key presses.
_onKeyup: function(dlg, methodName, e) {
var evt = e || window.event || {keyCode: 0};
if (evt.keyCode == 13) {
dlg[methodName]();
// Close dialog if method indicates cancel.
if (methodName == "invokeCancelCallback") {
dlg.hide();
}
}
},
_end: null
};
// Encapsulates "add comment" dialog.
var addCommentDialog = {
_dialogId: "share-dialog-addcomment",
_dialogContentId: "share-addCommentDlg",
_form: null,
_dlg: null,
_error: "share-error",
show: function(type, viewId) {
// Get dialog form.
this._form = document[this._dialogContentId];
// Clear error state.
dojo.removeClass(this._form, this._error);
// Set type
if (type) {
this._form.type.value = type;
}
// If provided a viewId (to add a comment to a picture), then put it
// in the proper input field.  Otherwise, use the current image's
// view id (from the imageSelection object; see above).
if (this._form.viewId) {
this._form.viewId.value = viewId || imageSelection.currentViewId();
if (this._form.viewId.value) {
this._form.viewId.disabled = false;
} else {
this._form.viewId.disabled = true;
}
}
if (!this._dlg) {
// Create the dialog.
var args = {
id: this._dialogId,
width: 500,
height: 200,
title: this.properties["share.addcomment.dlg.title"],
content: this._form
};
this._dlg = sflyWindowMgr.createWindow(args);
}
// Show the dialog.
this._dlg.show();
// Focus the textarea.
var textarea = this._form.text;
textarea.select();
// Focus text input when dialog appears.
if (!dojo.isIE) window.setTimeout("document[addCommentDialog._dialogContentId].text.focus()", 100);
},
submit: function() {
// Check for no input.
if (document[this._dialogContentId].text.value.length == 0) {
// Show prompt.
dojo.addClass( this._form, this._error);
} else {
// Clear text counter.
dojo.query("INPUT.share-textCounter", this._form)[0].value = "";
this._form.submit();
}
return false;
},
_end: null
}; // addCommentDialog
// Encapsulates "delete comment" confirmation dialog.  Some other confirmation
// dialogs (see below) are built on this one.
var deleteCommentDialog = {
_dialogId: "share-dialog-deletecomment",
_dialogContentId: "share-deleteCommentDlg",
_form: null,
_btnFixDelay: 100,
_titleTag: "share.deletecomment.dlg.title",
_type: null,
_viewId: null,
show: function(commentId, type, viewId) {
// Get dialog content.
var content = dojo.byId(this._dialogContentId);
if (!this._show(commentId, type, viewId)) {
return;
}
// Show the dialog.
var dialogParams = {
type: this._type || "confirm",
width: this._width || 400,
title: this.properties[this._titleTag],
content: content.innerHTML,
btnType: this._btnType || "yes",
icon: this._icon || "question",
okCallback: this._okCallback || dojo.hitch(this, "_submit")
};
if (this._focus) {
// Focus this field upon display.
dialogParams.focus = this._focus;
}
shareDialogMgr.showShareDialog(dialogParams, this);
},
_show: function(commentId, type, viewId) {
// Save args.
this._type = type;
this._viewId = viewId;
this._commentId = commentId;
return true;
},
_submit: function(forms) {
// Save form from dialog.
this._form = forms[0];
// Dialog has a form?
if (this._form) {
// Set type
if (this._type && this._form.type) {
this._form.type.value = this._type;
}
// If provided a viewId (to delete a comment from a picture), then put it
// in the proper input field.  Otherwise, use the current image's
// view id (from the imageSelection object; see above).
if (this._form.viewId) {
this._form.viewId.value = this._viewId || imageSelection.currentViewId();
}
// Set commentId if form has one.
if (this._form.commentId) {
this._form.commentId.value = this._commentId;
}
}
// Submit the form.
this.submit();
},
submit: function() {
// User said Ok, submit the form.
this._form.submit();
},
_end: null
}; // deleteCommentDialog
// DeleteItemsDialog; "derived" from deleteCommentDialog.
function deleteItemsDialogCtor() {};
var deleteItemsDialog = new (dojo.extend(deleteItemsDialogCtor, deleteCommentDialog));
deleteItemsDialog._dialogContentId = "share-deleteItemsDlg",
deleteItemsDialog._titleTag        = "share.deleteitems.dlg.title";
deleteItemsDialog._show = function() {
var viewIds = imageSelection.getSelectedViewIds();
if (viewIds.length == 0) {
shareDialogMgr.showShareDialog({        type: "alert"
,   btnType: "ok"
,   icon: "warning"
,   title: this.properties["share.noselection.dlg.title"]
,   content: this.properties["share.noselection.dlg.text"]
});
return false;
}
return true;
};
deleteItemsDialog.submit = function() {
var viewIds = imageSelection.getSelectedViewIds();
this._form.selectedItems.value = viewIds.join(",");
this._form.submit();
};
// orderPrintsDialog; "derived" from deleteCommentDialog.
function orderPrintsDialogCtor() {};
var orderPrintsDialog = new (dojo.extend(orderPrintsDialogCtor, deleteCommentDialog));
orderPrintsDialog._dialogContentId = "share-orderPrintsDlg",
orderPrintsDialog._titleTag        = "share.orderprints.dlg.title";
orderPrintsDialog._btnType         = "ok";
orderPrintsDialog._show = function() {
return true;
}
orderPrintsDialog.submit = function() {
// User said go ahead and order all.
imageSelection.selectAll();
imageSelection.orderPrints();
};
// savePicturesDialog; "derived" from deleteCommentDialog.
function savePicturesDialogCtor() {};
var savePicturesDialog = new (dojo.extend(savePicturesDialogCtor, deleteCommentDialog));
savePicturesDialog._dialogContentId = "share-savePicturesDlg",
savePicturesDialog._titleTag        = "share.savePictures.dlg.title";
savePicturesDialog._btnType         = "ok";
savePicturesDialog._show = function() {
return true;
}
savePicturesDialog.submit = function() {
// User said go ahead and order all.
imageSelection.selectAll();
imageSelection.savePictures();
};
// arrangePicturesDialog; "derived" from deleteCommentDialog.
function arrangePicturesDialogCtor() {};
var arrangePicturesDialog = new (dojo.extend(arrangePicturesDialogCtor, deleteCommentDialog));
arrangePicturesDialog._dialogContentId = "share-arrangePicturesDlg",
arrangePicturesDialog._titleTag        = "share.edit.arrange.dlg.title";
arrangePicturesDialog._btnType         = "ok";
arrangePicturesDialog._okTabIndex      = 4;
arrangePicturesDialog._focus           = "share-location";
arrangePicturesDialog._show = function() {
// Something selected?
if (imageSelection.getSelectedViewIds().length == 0) {
shareDialogMgr.showShareDialog({        type: "alert"
,   btnType: "ok"
,   icon: "warning"
,   title: this.properties["share.edit.arrange.noselection.dlg.title"]
,   content: this.properties["share.edit.arrange.noselection.dlg.text"]
});
return false;
}
// Generate <option>s for each picture.
var form = dojo.query("FORM", dojo.byId(this._dialogContentId))[0];
var sel = form["share-location"];
/* Stoopid IE - see http://support.microsoft.com/kb/276228
var opts = "";
for (var i = 0; i < shareEdit._imageCount; i++) {
opts += '<option value="' + i + '">' + (i + 1) + '</option>';
}
sel.innerHTML = opts;
*/
sel.innerHTML = "";
for (var i = 0; i < shareEdit._imageCount; i++) {
var opt = document.createElement("OPTION");
opt.value = i;
opt.innerHTML = i + 1;
sel.appendChild(opt);
}
return true;
};
arrangePicturesDialog.submit = function() {
var delta = this._form["share-beforeOrAfter"][0].checked ? 0 : 1;
var pos = parseInt(this._form["share-location"].value) + delta;
var selected = imageSelection.getSelectedViewIds();
// Put fake entry at end.  We need to "run off the end"
// of the list in order to trigger the code to append
// the selected items at the end, if the user said to
// move to after the last one.  By having a null entry
// at the end of the selected list, then we won't actually
// try to append the extra element.
selected.push(null);
var nextSelected = 0;
var viewIds = [];
for (var i = 0; i <= shareEdit._imageCount; i++) {
if (i == pos) {
// Note absolute position of where selected items are
// inserted; note that this might be different than "pos"
// (if some of the selected items come before this position).
imageSelection._arrangePos = viewIds.length;
// Clear "last selected" (shift-click after arrange gets too messy).
imageSelection._lastSelected = -1;
// Store that value in the cookie.
imageSelection._updateCookie();
// Add the selected viewIds here.
viewIds = viewIds.concat(selected);
// But not the fake one!
viewIds.pop();
}
// One of the selected ones?
var viewId = imageSelection.viewIdArray[i];
if (viewId == selected[nextSelected]) {
// Skip this one.
nextSelected++;
} else {
// Copy this image to output list.
viewIds.push(viewId);
}
}
// Fill form.
this._form.paths.value = viewIds.join(",");
// Disable dialog fields that don't get submitted.
dojo.forEach(["share-beforeOrAfter", "share-location"], function(id) {
this._form[id].disabled = true;
}, this);
if (dojo.isIE == 6) {
// Grrrr.  IE won't submit forms directly.  Do it this way...
imageSelection._submit(this._form);
} else {
// Do it the way any sane person would...
this._form.submit();
}
}
