<!--
  Usage Note:
  General syntax of instantiating thumbnail is as follows.

  1. Thumbnail for a specified image  
     <sds:thumbnail src="path_to_image_file" icon="path_to_icon_image_file"
       caption="caption_title" width="total_width" height="total_height"
	   style="position:absolute;" />
	   
	 Thumbnail size is scaled based on width and height specified.  the image
	 size is calculated such that the the entire thumbnail is fit into width
	 and height specified with maintaining original aspect ratio of the image.
	 
	 Alternative to width and height, imageWidth and imageHeight can be specified.
	 In this case the image specified in src will fit into imageWidth and
	 imageHeight with maintaining original aspect ratio of the image, and the
	 size of the entire thumbnail is calculated based on image size.

  2. Thumbnail for multiple pages
     <sds:thumbnail src="path_to_initial_image_file" icon="..." caption="..."
	   width="..." height="..." pages="num_of_pages" style="position:absolute;" />
	   
	 In this case, in addition to 1 above, pages must be specified.  Page navigation
	 bar appears in the thumbnail,and total pages and current page number are
	 displayed.
	 
	 Note: Calling script must implement changing image displayed as current page
	 is changed as following example.
	 
	 example:
	 <script language="JavaScript" for="thumbnail_id" event="onpagechange">
	 var thumb = document.all["thumbnail_id"];
	 var page = thumb.GetCurrentPage();
	 thumb.src = path_to_image_file_for_this_page;
	 </script>
	 
	 assuming that <sds:thumbnail id="thumbnail_id" ...>.
	 
  3. Drag enabled thumbnail
     <sds:thumbnail ... style="position:absolute; top:initial_top_position;
	   left:initial_left_position;" drag="true" />
	   
	 In this case, in addition to 1 and 2 above, drag="true" must be specified.
	 In addition, initial_top_position and initial_left_position must be specified
	 in absolute coordinate.  The thumbnails can be dragged and dropped within
	 browser's client area.
	 
  4. Thumbnail for specified file (Note: currently incomplete)
     <sds:thumbnail file="path_to_document_file"  width="total_width"
	   height="total_height" pages="num_of_pages" style="position:absolute;" />
	   
	 In this case, specifying file (which inidcates document file, not image file)
	 will automatically generate corresponding thumbnail image for pages of the
	 document file.  Properties; src, caption, and icon, are automatically deduced
	 from file property, and therefore need not be specified.  sDrag can be
	 supported as described in 3 above.

  Note for Thumbnail Selection and Deselection:
  
  The clients of thumbnail.htc file (HTML page which uses the thumbnail) must
  implement selection and deselection of thumbnails.  The thumbnail itself does not
  implement selection policies (for example, single selection vs. multiple selection
  on the page etc.), but fires onthumbnailselect and onthumbnaildeselect events.
  The following example implements simple single selection of thumbnail on the page.
  
  example:
  <script language="JavaScript" for="document" event="onclick()">
  var thumbs = document.all.tags("thumbnail");
  for(var i = 0; i < thumbs.length; i++)
  {
    if(!thumbs[i].contains(event.srcElement))
	{
	  if(thumbs[i].IsThumbnailSelected())
	    thumbs[i].DeselectThumbnail();
	}
  }
  </script>

  Depending on complexity of selection policy and event processing for a specific
  HTML page, more sophisticated processing based on processing onthumbnailselect
  and onthumbnaildeselect events may be necessary. 
-->

<PUBLIC:HTC URN="thumbnail">

<PUBLIC:PROPERTY NAME="src" />
<PUBLIC:PROPERTY NAME="file" />
<PUBLIC:PROPERTY NAME="icon" />
<PUBLIC:PROPERTY NAME="caption" />
<PUBLIC:PROPERTY NAME="pages" />
<PUBLIC:PROPERTY NAME="width" />
<PUBLIC:PROPERTY NAME="height" />
<PUBLIC:PROPERTY NAME="imageWidth" />
<PUBLIC:PROPERTY NAME="imageHeight" />
<PUBLIC:PROPERTY NAME="iconWidth" />
<PUBLIC:PROPERTY NAME="iconHeight" />
<PUBLIC:PROPERTY NAME="drag" />
<PUBLIC:PROPERTY NAME="pos" />
<PUBLIC:PROPERTY NAME="selfSelect" />

<PUBLIC:METHOD NAME="SelectThumbnail" />
<PUBLIC:METHOD NAME="DeselectThumbnail" />
<PUBLIC:METHOD NAME="IsThumbnailSelected" />
<PUBLIC:METHOD NAME="GetCurrentPage" />

<PUBLIC:EVENT ID="ThumbnailSelect" NAME="onthumbnailselect" />
<PUBLIC:EVENT ID="ThumbnailDeselect" NAME="onthumbnaildeselect" />
<PUBLIC:EVENT ID="ThumbnailClick" NAME="onthumbnailclick" />
<PUBLIC:EVENT ID="PageChange" NAME="onpagechange" />

<PUBLIC:ATTACH EVENT="ondocumentready" HANDLER="DoInit" />

<script language="JavaScript">
// global constants and variables
var DEFAULT_WIDTH = 200;
var DEFAULT_HEIGHT = 300;
var DEFAULT_ICON_WIDTH = 12;
var DEFAULT_ICON_HEIGHT = 15;
var MAX_PAGES = 20;

var CAPTION_HEIGHT = 20; 
var CAPTION_HANG = 10;
//Bug No:1337 - Baskaran.V
var IMAGE_OVERLAP = CAPTION_HANG / 5;
var SHADOW_OFFSET = CAPTION_HANG / 5;
var MARGIN = 2;
var page_info_height = 18;

// initialize thumbnail data and display
function DoInit()
{
  SetDefaults();
  BuildThumbnail();
  SetDisplayValues(); 
  SetImageSize();
  SetIconSize();	
  UpdateFileInfo();
}

function DoLoad()
{
  AdjustPosition();
  UpdatePageInfo();
  EnableDrag();
}

// set up defaults for properties when the user
// did not specify the value
function SetDefaults()
{
  if(src == null)
    src = "Images/null.gif";
  if(caption == null)
    caption = src;
  if(pages == null)
    pages = 1;
  if(width == null)
    width = DEFAULT_WIDTH;
  if(height == null)
    height = DEFAULT_HEIGHT;
  if(drag == null)
    drag = "false";
  if(selfSelect == null)
    selfSelect = "true";
  
  current_page = 1;
  thumbnail_selected = false;
}

function SetThumbnailSelection()
{
  if(thumbnail_selected == true)
  {
  	//Bug no: 1337 - Baskaran.V
  	caption_area.className = 'Thumbnail_caption_bgcolor';
	shadow_area.className = 'Thumbnail_bgcolor_selecttime';		
  }
  else
  {    
	//Bug no: 1337 - Baskaran.V
	caption_area.className = '';
	shadow_area.className = 'Thumbnail_bgcolor';		
  }
}

function SelectThumbnail()
{  
  if(thumbnail_selected == false)
  { 
    thumbnail_selected = true;
	SetThumbnailSelection();
 	element.style.zIndex = "1"; // put on top of others	
  }
  
  ThumbnailSelect.fire();		// fire onthumbnailselect event
}

function DeselectThumbnail()
{
  if(thumbnail_selected == true)
  {
    thumbnail_selected = false;
	SetThumbnailSelection();	// return to deselected visual state
	GetFirstPage();				// return to the first page
	element.style.zIndex = "0"; // return to normal z position
  }
  
  ThumbnailDeselect.fire();		// fire onthumbnaildeselect event
}

function IsThumbnailSelected()
{
  return thumbnail_selected;
}

function ThumbnailClicked()
{
  ThumbnailClick.fire();
}

function GetCurrentPage()
{
  return current_page;
}

function UpdateFileInfo()
{
  if(file != null)
    UpdateFileImageSource();
}

function UpdatePageInfo()
{
  if(current_page == 1)
    ClearPageInfo();
  else
  {
    var pages_displayed;
	
	// if more than MAX_PAGES in the document, append '+'
	if(pages > MAX_PAGES)
	  pages_displayed = MAX_PAGES + "+";
	else
	  pages_displayed = pages;
	 
	// set page info: example 'p2 / 16' 	
    page_info_text.innerHTML = "p" + current_page + " / " + pages_displayed;
	DisplayPageInfo();
  }	
}

// display page info area and page number
function DisplayPageInfo()
{
  page_info_area.style.display = "";
  page_info_text.style.display = "";
}

// clear page info area and page number
function ClearPageInfo()
{
  page_info_area.style.display = "none";
  page_info_text.style.display = "none";
}

function SetImageSize()
{
  // actual image width and height 
  var image_width;
  var image_height;
  
  // if both imageWidth and imageHeight attributes are specified,
  // size the entire thumbnail based on specified image width and height.
  // otherwise use width and height attributes
  if(imageWidth != null && imageHeight != null)
  {
    element.spec_width = imageWidth + CAPTION_HANG * 2;
	element.spec_height = imageHeight + CAPTION_HEIGHT - IMAGE_OVERLAP;
	
    image_width = imageWidth;
	image_height = imageHeight;
  }
  else
  {
    element.spec_width = width;
	element.spec_height = height;
	
    image_width = width - CAPTION_HANG * 2;
    image_height = height - CAPTION_HEIGHT + IMAGE_OVERLAP;
  }
  
  // do not resize if specified with file attribute
  // to get thumbnail of corresponding file
  if(file != null)
  {
    imageWidth = image_width;
	imageHeight = image_height;
	return;
  }
  
  if(image_width <= 0)
  {
    //alert("Invalid image width property value specified.");
	return;
  }

  if(image_area.width <= 0)
  {
    //alert("Invalid actual image width specified.");
	return;
  }
 
  // maintain aspect ratio, and adjust into specified
  // display width and height  
  var area_ar = image_height / image_width;
  var image_ar = image_area.height / image_area.width;

  if(image_ar >= area_ar)
  {
    image_area.height = image_height;
	image_area.width = image_height / image_ar;
  }
  else
  {
    image_area.width = image_width;
	image_area.height = image_width * image_ar;
  }

  image_width = image_area.width;
  image_height = image_area.height;

  width = image_area.width + CAPTION_HANG * 2;
  height = image_area.height + CAPTION_HEIGHT - IMAGE_OVERLAP;
}

function SetIconSize()
{
  if(file != null)
  {
    iconWidth = DEFAULT_ICON_WIDTH;
	iconHeight = DEFAULT_ICON_HEIGHT;
  }
  else
  {
    if(iconWidth != null && iconHeight != null)
    {
      icon_area.width = iconWidth;
	  icon_area.height = iconHeight;
    }
	else
	{
      icon_area.width = DEFAULT_ICON_WIDTH;
	  icon_area.height = DEFAULT_ICON_HEIGHT;
	}
  }
}

// set thumbnail position relative to absolute coordinate
// Note: needs to be called after SetImageSize() is called
function SetThumbnailPosition()
{
  var spec_height = element.spec_height;
  var spec_width = element.spec_width;
  
  // position thumbnail based on pos attribute specified.
  if(pos == "center" || pos == "c")
  {
    element.style.top = (spec_height - height) / 2;  
    element.style.left = (spec_width - width) / 2; 
  }
  else if(pos == "topLeft" || pos == "tl")
  {
    element.style.top = 0;
	element.style.left = 0;
  }
  else if(pos == "bottomRight" || pos == "br")
  {
    element.style.top = spec_height - height;
	element.style.left = spec_width - width;
  }
  else
  {
    // if pos is not specified, leave it in the original position
  }
}

// construct file string for <img> tag with specified syntax
// (use only when file attribute is specified)
function UpdateFileImageSource()
{	
  image_area.src = "sds://" + escape(file) +
                   "?width=" + imageWidth +
				   "?height=" + imageHeight +
				   "?page=" + current_page +
				   "?icon=" + "no";
  icon_area.src = "sds://" + escape(file) +
                  "?width=" + iconWidth +
				  "?height=" + iconHeight +
				  "?page=" + "1" +
				  "?icon=" + "only" +
				  "?iconSize=" + "small";
}

// display the first page of the document
function GetFirstPage()
{
  if(current_page != 1)
  {
    current_page = 1;
    if(file != null)	// if file attribute is specified
      UpdateFileImageSource();
    ClearPageInfo(); 
    PageChange.fire();
  }
}

function GetPrevPage()
{
  if(current_page > 1)
  {
    current_page--;
    UpdatePageInfo();
    PageChange.fire();	// fire onpagechange event
  }
}

function GetNextPage()
{
  if(current_page < pages && current_page < MAX_PAGES)
  {
    current_page++;
    UpdatePageInfo();
    PageChange.fire();	// fire onpagechange event
  }
}

// use this function only when file attribute is specified
function GetPrevFilePage()
{
  if(current_page > 1)
  {
    current_page--;
    UpdateFileImageSource();
    UpdatePageInfo();
    PageChange.fire();
  }
}

// use this function only when file attribute is specified
function GetNextFilePage()
{
  if(current_page < pages && current_page < MAX_PAGES)
  {
    current_page++;
    UpdateFileImageSource();
    UpdatePageInfo();
    PageChange.fire();
  }
}

// constuct the entire thumbnail image from seveal <div> and <img> tags,
// then attach events
function BuildThumbnail()
{
  // Note: uniqueID is used to get unique string for each instance of thumbnail
  // ('uniqueID' is element's property as extension to DHTM object model)
  var html_text =
    '<div id="thumbnail_area_' + uniqueID + '" style="position:absolute; cursor:hand;">' +
    '  <div id="caption_area_id" align="center" nowrap style="position:absolute;' +
	        'font-family:Arial, Helvetica, sans-serif; font-size: 8pt; padding-top:75px;">'+ 	
    '	   </div>' +
    '  <img id="image_area_id" style="position:absolute; border-color:#7b828c;" border="0">' + 
    '  <img id="icon_area_id" style="position:absolute; z-index:1">' +
    '  <div id="shadow_area_id" style="position:absolute; z-index:-1;"></div>' +
    '  <div id="page_area_id">' +
    '    <img id="prev_page_area_id" src="Images/prev_page.gif" style="position:absolute;">' + 
    '    <img id="next_page_area_id" src="Images/next_page.gif" style="position:absolute;">' +   
    '    <img id="page_info_area_id" src="Images/null.gif" style="position:absolute;" border="1">' +
    '    <div id="page_info_text_id" style="position:absolute; color:#000080; ' +
	          'font-family: Arial, Helvetica, sans-serif; font-size: 8pt;"></div>' +
    '  </div>' +
    '</div>';

  innerHTML = html_text;
  
  // create short-hand notation for reference to elements within thumbnail.
  // all values (thumbnail_area, caption_area, etc.) will become element's
  // attributes.
  thumbnail_area = all["thumbnail_area_" + uniqueID];
  caption_area = thumbnail_area.all["caption_area_id"];
  image_area = thumbnail_area.all["image_area_id"];
  icon_area = thumbnail_area.all["icon_area_id"];
  shadow_area = thumbnail_area.all["shadow_area_id"];
  page_area = thumbnail_area.all["page_area_id"];
  prev_page_area = thumbnail_area.all["prev_page_area_id"];
  next_page_area = thumbnail_area.all["next_page_area_id"];
  page_info_area = thumbnail_area.all["page_info_area_id"];
  page_info_text = thumbnail_area.all["page_info_text_id"];
 
  // attach events to appropriate elements within thumbnail
  if(selfSelect == "true")
    thumbnail_area.attachEvent("onclick", SelectThumbnail);
  else
    thumbnail_area.attachEvent("onclick", ThumbnailClicked);
 
  image_area.attachEvent("onload", DoLoad);
  
  if(file == null)
  {
    prev_page_area.attachEvent("onclick", GetPrevPage);
    next_page_area.attachEvent("onclick", GetNextPage);
  }
  else
  {
    prev_page_area.attachEvent("onclick", GetPrevFilePage);
    next_page_area.attachEvent("onclick", GetNextFilePage);
  }
}

// retrieve file name from file spec (entire file path)
function GetFileName(file_path)
{
	var path_fragment = file_path.split("/");
	var len = path_fragment.length;
	var file_name = path_fragment[len - 1];
	
	return file_name;
}

function SetDisplayValues()
{
  // if file attribute is not specified, src attribute is used
  // to display image.
  // otherwise, file attribute is used to display image.  
  if(file == null)
  {
    caption_area.innerHTML = caption;
    image_area.src = src;      
    if(icon == null)	// if icon is not specified, do not display it
      icon_area.style.display = "none";
    else
      icon_area.src = icon;
  }
  else
  {	
    caption_area.innerHTML = GetFileName(file);
  }
  
  SetThumbnailSelection();
}

// set up size of page info area and text size
// depending on size of the image
function SetPageInfoAreaSize()
{
  var ih = image_area.height;
  
  if(ih > 60)
  {
    page_info_height = 18;
	font_size = 8;
  }
  else if(ih > 30)
  {
    page_info_height = 14;
	font_size = 7;
  }
  else
  {
    page_info_height = 10;
	font_size = 6;
  }

  page_info_text.style.fontSize = font_size + "pt";  
}

// set positions of all elements which constitues thumbnail.
// all positioning is in absolute coordinate.
function AdjustPosition()
{
  width = image_area.width + CAPTION_HANG * 2;
  height = image_area.height + CAPTION_HEIGHT - IMAGE_OVERLAP;
  
  SetThumbnailPosition();
  SetPageInfoAreaSize();
  
  var iw = image_area.width;
  var ih = image_area.height;
  var ib = parseInt(image_area.border);
  var pb = parseInt(page_info_area.border);
  var it = CAPTION_HEIGHT - IMAGE_OVERLAP;
  var il = CAPTION_HANG -17;
  var w = iw + ib * 2;
  var h = ih + ib * 2;
 
  caption_area.style.pixelWidth = w + CAPTION_HANG * 2;
  caption_area.style.pixelHeight = CAPTION_HEIGHT;

  image_area.style.pixelTop = it-15;
  image_area.style.pixelLeft = il+15;
  
  icon_area.style.pixelTop = (it + h - ib - icon_area.height - MARGIN)-15; 
  icon_area.style.pixelLeft = (il + ib + MARGIN)+15;

  shadow_area.style.pixelWidth = w+3;
  shadow_area.style.pixelHeight =h+3;
  shadow_area.style.pixelTop = it + SHADOW_OFFSET-18;
  shadow_area.style.pixelLeft = il + SHADOW_OFFSET+12;

  prev_page_area.style.pixelTop = it;
  prev_page_area.style.pixelLeft = il - prev_page_area.width - MARGIN;
  next_page_area.style.pixelTop = it;
  next_page_area.style.pixelLeft = il + w + MARGIN;

  page_info_area.style.pixelWidth = w - pb * 2;
  page_info_area.style.pixelHeight = page_info_height;
  page_info_area.style.pixelTop = it + ib + ih - page_info_height - pb;
  page_info_area.style.pixelLeft = il;
  page_info_area.style.backgroundColor = "";

  page_info_text.style.pixelWidth = w - pb * 2;
  page_info_text.style.pixelHeight = page_info_height;
  page_info_text.style.pixelTop = it + ib + ih - page_info_height - pb + MARGIN;
  page_info_text.style.pixelLeft = il + ib + icon_area.width + MARGIN * 2;

  var rw = caption_area.offsetWidth +45;
  var nw =(w + CAPTION_HANG * 2)+45;

  // if the caption text is longer than caption title area,
  // cut off the text and append '...'. 
  if(rw > nw)
  {
    var text = caption_area.innerHTML;
    var num_ch = ((text.length - 2) * nw) / rw;
    caption_area.innerHTML =
      "&nbsp;" + text.substr(0, num_ch) + "..." + "&nbsp;";
  }

  // page info is displayed only when display is
  // not in the first page
  if(pages > 1)
    page_area.style.display = "";
  else
    page_area.style.display = "none";
}

// drag and drop support functionality

var dragged_element = null;	// currently dragged element

// attach approprate events for drag-and-drop support
function EnableDrag()
{
  // only when dragEnabled attribute is set to trues
  if(drag == "true")
  {
    element.document.attachEvent("onmousedown", MouseDown);
    element.document.attachEvent("onmousemove", MouseMove);
    element.document.attachEvent("onmouseup", ResetDrag);
    element.document.attachEvent("ondragstart", IsSelectable);
    element.document.attachEvent("onselectstart", IsSelectable);
  }
}

// clear dragged element
function ResetDrag()
{
  dragged_element = null;
}

// update thumbnail position based on mouse movement
function MouseMove()
{
  // only if left mouse button is pressed and
  // an element is currently dragged
  if((event.button == 1) && (dragged_element != null))
  {
    // get absolute position of mouse click
    var absTop = event.clientY + element.document.body.scrollTop;
	var absLeft = event.clientX + element.document.body.scrollLeft;

    // get total offset of dragged element	
	var offsetTop = 0;
	var offsetLeft = 0;
	var current_element = dragged_element.offsetParent;

	while(current_element.offsetParent != null)
	{
	  offsetTop += current_element.offsetTop;
	  offsetLeft += current_element.offsetLeft;
	  current_element = current_element.offsetParent;
	}
	
	// set updated position of dragged element
	dragged_element.style.pixelTop = absTop - offsetTop - dragged_element.y;
	dragged_element.style.pixelLeft = absLeft - offsetLeft - dragged_element.x;
	
	// cancel default processing of this event
	event.returnValue = false;
  }
}

// retrieve thumbnail element to be dragged from its sub-element
function ElementToDrag(el)
{
  if(el != null)
  {
	if(element.contains(el))
	  return element;
  }
  return null;
}

// get mouse position when mouse button is pressed within thumbnail area
function MouseDown()
{
  var current_element = ElementToDrag(event.srcElement);
  
  // only when mouse button is pressed within thumbnail
  if(current_element != null)
  {
    dragged_element = current_element;
	dragged_element.x = event.offsetX;
	dragged_element.y = event.offsetY;
	var el = event.srcElement;
	
	// save position of dragged element as offset from top offset parent
	if(dragged_element != el.offsetParent && dragged_element != event.srcElement)
	{
	  while(el != dragged_element)
	  {
	    dragged_element.x += el.offsetLeft;
		dragged_element.y += el.offsetTop;
		el = el.offsetParent;
	  }
	}
  }
}

// examine if default selection processing can be performed
function IsSelectable()
{
  // disable default selection for currently dragged
  // element and sub-elements (i.e. selection of text within thumbnail)
  return (ElementToDrag(event.srcElement) == null && dragged_element != null);
}

</script>

</PUBLIC:HTC>