﻿// Globals:
//     AoMTypes - from SidebarCacheObjects.js
//     assetPageConsts
//     assetPage (AssetPage object)
//     assetPageCB

var assetPageConsts = {
  DATE_1: 1, /* July 2, 2007         */
  DATE_2: 2, /* July 2               */
  DATE_3: 3, /* 07/02/2007           */
  TIME_1: 4, /* 13:25                */
  TIME_2: 5, /* 1:25pm               */
  TIME_3: 6, /* 1pm                  */
  DATE_TIME_1: 7, /* July 2, 2007, 1:25pm */
  DATE_TIME_2: 8, /* 06/04/2008 15:33     */
  FLASH_DATE:  9, /* May/13/2006 22:26    */
  SAME_ALBUM: 0,
  SAME_TIMELINE: 1,
  SAME_TAB: 2,
  SAME_TYPE: 3,
  BOTTOM_SHORT: 30,
  BOTTOM_TALL: 30,
  ASSET: 0,  /* view mode: asset */
  ALBUM: 1,  /* view mode: album */
  ASSET_IN_ALBUM: 2   /* view mode: navigating assets in album */
}

var datePrecisions = {
  MILISECOND: 0,
  SECOND: 1,
  MINUTE: 10,
  HOUR: 20,
  DAY: 30,
  MONTH: 40,
  YEAR: 50,
  DECADE: 60,
  CENTURY: 70,
  MILLENIUM: 80,
  UNKNOWN: 9999
}

var dateReversePrecisions = {
  "minute": datePrecisions.MINUTE,
  "hour": datePrecisions.HOUR,
  "date": datePrecisions.DAY,
  "month": datePrecisions.MONTH,
  "year": datePrecisions.YEAR
}

var datePrecisionsEnum = ["minute", "hour", "date", "month", "year"];

//var assetPageUserTags = "undefined";
var assetPageApiQueue = new AssetPageApiQueue();
var assetPageDropdownTimeout = false;

// Callbacks from Flash [start]

function assetPageLoadAsset(obj) {
  if (typeof (obj) == undefined) {
    return;
  }
  assetPage.navigateAsset(obj);
}

// AssetPage class [start]

function AssetPage() {
  this.viewerID = flashvars.Viewer;
  this.loadInterval = 0;
  this.assetData = {};
  this.assetDate = 0;
  this.comments = [];
  this.controls = new Object();
  this.controls.share = new AssetPageControl(this, "share");
  this.controls.tag = new AssetPageControl(this, "tag");
  this.controls.person_markers = new AssetPageControl(this, "person_markers");
  this.controls.time_stamp = new AssetPageControl(this, "time_stamp");
  this.flashAsset = new Object();
  this.timeSlider = new AssetPageTimestampSlider(this);
  this.navigationType = assetPageConsts.SAME_TAB;
  this.state = 0;
  this.titleBgTimeout = 0;
  this.viewMode = assetPageConsts.ASSET;
  this.history = new Object();
  this.isLoggedIn = (flashvars.IsLoggedIn == "true");
  this.message = new AssetPageMessage();
  this.queueDateChanges = new Object();
  assetPageCB = new AssetPageCB();
  $get("AssetPage_container").onscroll = AssetPageScroll;
  this.necessaryDataLoaded = {
    AomTypes: false,
    ContactCloud: false,
    AssetData: false,
    BalloonOpened: false
  }
  // removed for now: UserTagsFetched: false

  // preloading images:
  this.preloadImages = [
  { img: new Image(), src: "/Images/sidebar/arw_dwn.png" },
  { img: new Image(), src: "/Images/AssetPage/timestamp_slider_transparent.png"}];

  for (var i in this.preloadImages) {
    this.preloadImages[i].img.src = this.preloadImages[i].src;
  }
}

AssetPage.prototype.prepareContents = function(fromWhere, navMode) {
  var params, loader;
  this.viewMode = navMode;
  // general information for all assets, will be loaded once:
  AoMTypes.load();     // All AomTypes
  if (this.isLoggedIn)
    ContactCloud.load(); // Contact cloud
  this.fillTagList();  // All user's tags
  switch (fromWhere) {
    case "balloon":
      this.necessaryDataLoaded.BalloonOpened = false;
      break;
    case "Navigation":
      this.necessaryDataLoaded.BalloonOpened = true;
      break;
    case "AlbumNavigation":
      this.necessaryDataLoaded.BalloonOpened = true;
      break;
    default:
  }

  switch (this.flashAsset.Type) {
    case "Album":
      params = new Array(
            { name: "Owner", value: this.flashAsset.OwnerID },
            { name: "AlbumID", value: this.flashAsset.ID },
            { name: "SerType", value: 2 },
            { name: "TimelineID", value: this.flashAsset.TimelineID });
            executeWebRequest("Albums.GetBalloon", params, { onSuccessFunction: assetPageCB.getAssetDetails, onFailureFunction: assetPageCB.fail });
      this.necessaryDataLoaded.AssetData = false;    
      this.viewMode = assetPageConsts.ALBUM;
      break;
    case "Asset":
      params = new Array(
            { name: "Owner", value: this.flashAsset.OwnerID },
            { name: "AssetID", value: this.flashAsset.ID },
            { name: "SerType", value: 2 },
            { name: "TimelineID", value: this.flashAsset.TimelineID });
      if (typeof (this.flashAsset.parent) == "object") {
        this.parentAlbum = this.flashAsset.parent;
        this.viewMode = assetPageConsts.ASSET_IN_ALBUM;
      }
      executeWebRequest("Assets.GetAssetDetails", params, { onSuccessFunction: assetPageCB.getAssetDetails, onFailureFunction: assetPageCB.fail });
      this.necessaryDataLoaded.AssetData = false;
      break;
  }
  if (this.loadInterval != 0)
    clearInterval(this.loadInterval);
  this.loadInterval = setInterval(ContextDelegate(this, this.dataLoaded), 500);
}

AssetPage.prototype.dataLoaded = function() {
  var prop, i, params;
  this.necessaryDataLoaded.AomTypes = AoMTypes.isLoaded;
  this.necessaryDataLoaded.ContactCloud = this.isLoggedIn ? ContactCloud.isLoaded : true;
  for (prop in this.necessaryDataLoaded) {
    if (this.necessaryDataLoaded[prop] == false) return false;
  }

  // Getting comments:
  $get("AssetPage_comments_AddYourComment").style.display = this.assetData.CanComment ? "block" : "none";
  params = new Array(
    { name: "EntityID", value: this.assetData.ID },
    { name: "SerType", value: 2 },
    { name: "Skip", value: 0 },
    { name: "Take", value: 100 });
  executeWebRequest("Comments.GetComments", params, { onSuccessFunction: function(data) { assetPage.setComments(data); }, onFailureFunction: assetPageCB.fail });

  // Getting tags:
  params = new Array(
  { name: "EntityID", value: this.assetData.ID },
  { name: "SerType", value: 2 });
  executeWebRequest("Tags.GetEntityTags", params, { onSuccessFunction: function(data) { assetPage.setTags(data); }, onFailureFunction: assetPageCB.fail });

  switch (this.viewMode) {
    case assetPageConsts.ASSET:
    case assetPageConsts.ASSET_IN_ALBUM:
      this.assetDataLoaded();
      break;
    case assetPageConsts.ALBUM:
      this.albumDataLoaded();
  }
  this.completeLoading();
}

AssetPage.prototype.albumDataLoaded = function() {
  var prop, i, params;
  this.resetControls();
  this.assetData.When = this.flashAsset.When;
  this.assetData.CanChangeDate = false;
  this.parentAlbum = this.flashAsset; // preparing for displaying sub-assets in album
  $get("AssetPage_AomType_title").className = "";
  $get("AssetPage_AomType_icon").style.backgroundImage = "url('/Images/Sidebar/sd_ico_album.png')";
  $get("AssetPage_AomType_icon").style.backgroundPosition = "0px 0px";
  $get("AssetPage_AomType_title").innerHTML = "Album";
  $get("AssetPage_description_text").innerHTML = "";
  $get("AssetPage_description_editor").style.display = "none";
  $get("AssetPage_description_edit").style.visibility = "hidden";
  // Displaying in HTML viewer:
  this.albumObject = new AssetPageAlbum(this);
  this.player = AssetPagePlayersFactory("Album", this);
  this.player.init();
  $get("AssetPage_add_person_marker").style.visibility = "hidden";
  $get("AssetPage_add_image_note").style.visibility = "hidden";
  $get("AssetPage_num_views_container").style.visibility = "hidden";
  // Notifying server

  params = new Array(
    { name: "AlbumID", value: this.assetData.ID },
    { name: "Owner", value: this.flashAsset.OwnerID },
    { name: "TimelineID", value: this.flashAsset.TimelineID },
    { name: "SerType", value: 2 });
  executeWebRequest("Albums.IncrementPageViews", params, { onSuccessFunction: function(data) {  }, onFailureFunction: function() { } });
}

AssetPage.prototype.assetDataLoaded = function() {
  $get("AssetPage_AomType_icon").style.backgroundImage = "url('" + AoMTypes[this.assetData.AomTypeID].IconURL + "')";
  $get("AssetPage_AomType_icon").style.backgroundPosition = "-100px -4px";
  var validOriginURL = true;
  if (this.assetData.OriginURL == null)
    validOriginURL = false;
  else if (this.assetData.OriginURL.indexOf("http://") == -1)
    validOriginURL = false;
  if (validOriginURL)
    $get("AssetPage_AomType_title").className = "AssetPage_link";
  else
    $get("AssetPage_AomType_title").className = "";
  $get("AssetPage_AomType_title").innerHTML = AoMTypes[this.assetData.AomTypeID].AssetPageTitle;
  $get("AssetPage_description_text").innerHTML = this.assetData.Description;
  if (this.assetData.Description == "") {
    $get("AssetPage_description_edit").innerHTML = "Write description";
  } else {
    $get("AssetPage_description_edit").innerHTML = "Edit description";
  }
  $get("AssetPage_description_edit").style.visibility = this.assetData.CanChangeTexts ? "visible" : "hidden";
  $get("AssetPage_comment_textarea").value = "";

  // Displaying markers
  if (AoMTypes[this.assetData.AomTypeID].PlayerName != "AomImagePlayer")
    this.assetData.CanAddMarker = false;

  this.enableAddPersonMarkers();
  // Displaying in HTML viewer:
  this.player = AssetPagePlayersFactory(AoMTypes[this.assetData.AomTypeID].PlayerName, this);
  this.player.init();
  $get("AssetPage_add_person_marker").style.visibility = "visible";
  $get("AssetPage_add_image_note").style.visibility = "visible";
  $get("AssetPage_num_views_container").style.visibility = "visible";

  // Getting markers:
  if (this.isLoggedIn) {
    params = new Array({ name: "AssetID", value: this.assetData.ID }, { name: "SerType", value: 2 });
    executeWebRequest("Assets.GetMarkers", params, { onSuccessFunction: function(data) { assetPage.setMarkers(data); }, onFailureFunction: assetPageCB.fail });
  } else {
    this.controls.person_markers.enable(false);
  }
}

AssetPage.prototype.completeLoading = function() {
  clearInterval(this.loadInterval);
  this.loadInterval = 0;
  this.message.stopProcessing(true);
  this.assetData.TimelineID = "" + this.flashAsset.TimelineID;
  this.assetData.OwnerID = "" + this.flashAsset.OwnerID;
  if (this.viewMode == assetPageConsts.ASSET_IN_ALBUM) {
    var iconUrl = ReplaceAll(this.assetData.Url, "{0}", "I");
    var assetLocationInAlbum;
    $get("AssetPage_asset_title").style.display = "none";
    $get("AssetPage_album_asset_title_container1").style.display = "block";
    $get("AssetPage_album_asset_title_container2").style.display = "block";
    $get("AssetPage_album_asset_parent_title").innerHTML = this.parentAlbum.Title;
    $get("AssetPage_album_asset_title").innerHTML = this.assetData.Title;
    $get("AssetPage_album_asset_icon").style.backgroundImage = "url('" + iconUrl + "')";
    assetLocationInAlbum = "[Asset ";
    for (var i = 0; i < this.parentAlbum.assetArray.length; i++) {
      if (this.parentAlbum.assetArray[i].ID == this.assetData.ID) {
        assetLocationInAlbum += (++i);
        break;
      }
    }
    assetLocationInAlbum += " of " + this.parentAlbum.assetArray.length + " in album]";
    $get("AssetPage_asset_in_album").innerHTML = assetLocationInAlbum;
  } else {
    $get("AssetPage_asset_title").style.display = "block";
    $get("AssetPage_album_asset_title_container1").style.display = "none";
    $get("AssetPage_album_asset_title_container2").style.display = "none";
    $get("AssetPage_asset_title").innerHTML = this.assetData.Title;
    $get("AssetPage_asset_in_album").innerHTML = "";
  }
  this.assetDate = new AssetPageDate(this.assetData.When, this.assetData.Precision, "string");
  this.assetDate.updateFields();
  $get("AssetPage_date_change").style.display = this.assetData.CanChangeDate ? "block" : "none";
  if (this.assetData.CreatorAoMURL == "" || this.assetData.CreatorAoMURL == null)
    $get("AssetPage_first_brought_name").innerHTML = this.assetData.CreatorName;
  else
    $get("AssetPage_first_brought_name").innerHTML = buildContactLink(this.assetData.CreatorAoMURL, this.assetData.CreatorName);
  $get("AssetPage_num_views").innerHTML = this.assetData.NumViews;
  $get("AssetPage_add_image_note").className = "AssetPage_float_left AssetPage_action_disabled"
  $get("AssetPage_add_image_note").style.backgroundImage = "url(/Images/AssetPage/image_note_icon_dis.gif)";
  $get("AssetPage_add_image_note").onclick = null;
  $get("AssetPage_add_image_note").className = "AssetPage_float_left AssetPage_action_disabled"
  $get("AssetPage_add_image_note").style.backgroundImage = "url(/Images/AssetPage/image_note_icon_dis.gif)";
  $get("AssetPage_add_image_note").onclick = null;

  this.setTime(this.assetDate.date);
  $get("AssetPage_time_stamp_edit").style.display = this.assetData.CanChangeDate ? "block" : "none";
  $get("AssetPage_sub_container").style.display = "block"
  $get("AssetPage_container").style.display = "block";
  if (this.assetData.CanChangeDate) {
    this.controls.time_stamp.enable(true);
    if (this.controlToOpen == "changeTime")
      this.controls.time_stamp.open();
  } else {
    this.controls.time_stamp.enable(false);
  }
  // getting sharing:
  params = new Array(
  { name: "AssetID", value: this.assetData.ID },
  { name: "SerType", value: 2 });
  executeWebRequest("Assets.GetTargets", params, { onSuccessFunction: function(data) { assetPage.setShare(data); }, onFailureFunction: assetPageCB.fail });

  // stars
  this.starsController = new AssetPageStars(this.assetData.ID, this.flashAsset.OwnerID, this.assetData.RatingAvg, this.assetData.CanRate, this.assetData.NumRaters);
}
  

// set controls and Comments set [start]

AssetPage.prototype.setComments = function(curData) {
  var i;
  this.assetData.comments = curData;
  $get("AssetPage_comments_header").style.display = this.assetData.comments.length ? "block" : "none";
  this.comments = new AssetPageComments(this);
  if (this.assetData.comments.length) {
    for (i = 0; i < this.assetData.comments.length; i++) {
      this.comments.addComment(this.assetData.comments[i]);
    }
  }
  $get("AssetPage_comments_container").innerHTML = this.comments.getHtml();
  $get("AssetPage_comments_container").style.display = "block";
}

AssetPage.prototype.setShare = function(curData) {
    var isChecked;
    var shareGroupsElements;
    var shareWithNames;
    var shareGroupsHTML;
    var groupCount;
    this.assetData.share = curData;
    shareWithNames = this.getShareWithNames();

    groupCount = 0;
    shareGroupsHTML = "";

    var checkboxElements = document.getElementsByName("AssetPage_ShareWith");
    checkboxElements[0].checked = false;
    checkboxElements[1].checked = false;
    // Oded - iContact instead of i; iGroup instead of j
    for (var iContact in ContactCloud) {
      if (ContactCloud[iContact].TargetTypeID == TargetTypes.GROUP) {
        if (ContactCloud[iContact].RealGroup) {
          isChecked = "";
          for (var iGroup in this.assetData.shareGroups) {
            if (this.assetData.shareGroups[iGroup] == iContact) {
              isChecked = ' checked="true"';
              break;
            }
          }
          shareGroupsHTML += '\
            <div class="ShareLine">\
            <div><input id="AssetPageShareCB_' + iContact + '" type="checkbox" name="AssetPage_ShareWith" onclick="assetPage.shareSelectionChanged(this.checked, \'group\');"' + isChecked + ' /></div>\
            <div><div class="Icon GroupContactImage"></div></div>\
            <div>' + ContactCloud[iContact].Name + '</div>\
            </div>\
            <div class="ShareLineBreak"></div>';
          groupCount++;
        }
      }
    }

    $get("AssetPage_share_groups").innerHTML = shareGroupsHTML;

    // Oded - if PUBLIC is targeted - check all the boxes; if NETWORK is targeted - check network and all the groups
    for (var iGroup = 0; iGroup < this.assetData.shareGroups.length; iGroup++) {
      switch (this.assetData.shareGroups[iGroup]) {
        case TargetTypes.PUBLIC:
          for (var iCheckbox = 0; iCheckbox < checkboxElements.length; iCheckbox++) {
            checkboxElements[iCheckbox].checked = true;
          }
          break;

        case TargetTypes.NETWORK:
          for (var iCheckbox = 1; iCheckbox < checkboxElements.length; iCheckbox++) {
            checkboxElements[iCheckbox].checked = true;
          }
          break;

        default:
          for (var iCheckbox = 0; iCheckbox < checkboxElements.length; iCheckbox++) {
            if (checkboxElements[iCheckbox].id == "AssetPageShareCB_" + this.assetData.shareGroups[iGroup]) {
              checkboxElements[iCheckbox].checked = true;
            }
          }
        }
    }
    $get("AssetPage_share_control_closed").innerHTML = shareWithNames;
    $get("AssetPage_share_edit").style.display = this.assetData.CanShare ? "block" : "none";
    this.controls.share.enable(this.assetData.CanShare);
    if (this.controlToOpen == "share" && this.assetData.CanShare) {
        this.controls.share.open();
    }
}


AssetPage.prototype.getShareWithNames = function() {
    this.assetData.shareGroups = new Array();
    var shareWithNames = "";
    var addedNetwork = false;
    var addedGroups = false;
    // Oded
    for (var i = 0; i < this.assetData.share.length; i++) {
        if (typeof (ContactCloud[this.assetData.share[i].ID]) == "undefined") continue;

        if (shareWithNames != "") shareWithNames += ", ";
        shareWithNames += ContactCloud[this.assetData.share[i].ID].Name;

        switch (ContactCloud[this.assetData.share[i].ID].TargetTypeID) {
            case TargetTypes.PUBLIC:
                this.assetData.shareGroups.push(this.assetData.share[i].ID);
                break;

            case TargetTypes.NETWORK:
                this.assetData.shareGroups.push(this.assetData.share[i].ID);
                break;

            case TargetTypes.GROUP:
                this.assetData.shareGroups.push(this.assetData.share[i].ID);
                break;

            default:
                // The target is a user - do nothing since there's no check box
        }
    }
    return shareWithNames;
}

AssetPage.prototype.setTags = function(curData) {
  var i, tagsHtml, userTagsHtml, escapedTagForJS;

    this.assetData.tags = new Object();
  tagsHtml = "";
  shortTagsHtml = "";
  if (curData.length) {
    tagsHtml += '\
    <div class="HeaderText">Current Tags:</div>\
    <div id="AssetPage_tag_control_list">';
    for (i = 0; i < curData.length; i++) {
      this.assetData.tags[curData[i].ID] = curData[i];
      tagsHtml += getTagListLine(curData[i]);
      if (i < 6) {
      if (i > 0) shortTagsHtml += " ";
      shortTagsHtml += curData[i].Title;
    }
  }
  tagsHtml += '\
  </div>\
  <div class="hr"></div>';
  }
  $get("AssetPage_tag_control_current_tags").innerHTML = tagsHtml;
  $get("AssetPage_tag_control_closed").innerHTML = shortTagsHtml;
  /*
  if (typeof (assetPageUserTags) == "object") {
  userTagsHtml = '\
  <div><strong>Or choose from your tags:</strong></div>\
  <div id="AssetPage_TagWindowTagList">';
  i = "";
  for (i in assetPageUserTags) {
  escapedTagForJS = assetPageUserTags[i].replace(/\"+/g, '\\"');
  escapedTagForJS = escapedTagForJS.replace(/\'+/g, "\\'");
  userTagsHtml += '\
  <span class="click_tag"\
  onclick="javascript: addTagToTextbox(\'' + escapedTagForJS + '\', \'AssetPage\');">'
  + assetPageUserTags[i] + '</span>&nbsp;';
  }
  userTagsHtml += '</div>';
  if (i != "")
  $get("AssetPage_tag_control_your_tags").innerHTML = userTagsHtml;
  }
  */
  this.controls.tag.enable(this.assetData.CanTag);
  if (this.controlToOpen == "tag" && this.assetData.CanTag) {
    this.controls.tag.open();
  }
}

AssetPage.prototype.setTime = function(curDate) {
  var curYear, curSelectTag, curOptions;
  curYear = curDate.getFullYear();
  if (typeof (curDate) == "undefined") curDate = this.assetDate.date;
  var selectedDefaults = { month: "--", day: "--", hour: "--", minute: "--" };
  if (this.assetData.Precision <= datePrecisions.MONTH)
    selectedDefaults.month = curDate.getMonth()
  if (this.assetData.Precision <= datePrecisions.DAY)
    selectedDefaults.day = curDate.getDate()
  if (this.assetData.Precision <= datePrecisions.HOUR)
    selectedDefaults.hour = curDate.getHours()
  if (this.assetData.Precision <= datePrecisions.HOUR)
    selectedDefaults.minute = curDate.getMinutes()
  curOptions = createListOptions(this.assetDate.shortMonthNames, selectedDefaults.month, true);
  $get("AssetPage_time_stamp_change_month_container").innerHTML = createDateSelectTag("month", curOptions);
  $get("AssetPage_time_stamp_change_year").value = curYear;
  curOptions = createRangeOptions(1, getDaysInMonth(curDate), selectedDefaults.day, false, true);
  $get("AssetPage_time_stamp_change_date_container").innerHTML = createDateSelectTag("date", curOptions);
  curOptions = createRangeOptions(0, 59, selectedDefaults.minute, true, true);
  $get("AssetPage_time_stamp_change_minute_container").innerHTML = createDateSelectTag("minute", curOptions); ;
  curOptions = createRangeOptions(0, 23, selectedDefaults.hour, false, true);
  $get("AssetPage_time_stamp_change_hour_container").innerHTML = createDateSelectTag("hour", curOptions);
}

AssetPage.prototype.setMarkers = function(curData) {
  this.assetData.markers = curData;
  markerController.queueMarkers(MarkerConsts.PERSON_MARKER, this.assetData.markers);
  this.controls.person_markers.enable(curData.length);
  this.setMarkerElements();
}

AssetPage.prototype.setMarkerElements = function() {
  var markedUsersShort = markedUsersLong = "";
  var curMarkedUser, curSplit;
  var userLink;
  var ageElements = new Array();
  var displayedMarkers = new Object();
  for (var i = 0; i < this.assetData.markers.length; i++) {
    if (this.assetData.markers[i].MarkedUserName != "") {
      if (displayedMarkers[this.assetData.markers[i].MarkedUserID] == undefined) {
        displayedMarkers[this.assetData.markers[i].MarkedUserID] = true;
        curMarkedUser = this.assetData.markers[i].MarkedUserName;
        curSplit = curMarkedUser.split(" ");
        if (markedUsersShort != "") markedUsersShort += ", ";
        markedUsersShort += curSplit[0];
        if (markedUsersLong != "") markedUsersLong += ",<br />";
        if (this.assetData.markers[i].MarkedUserAoMURL == "")
          markedUsersLong += curMarkedUser;
        else
          markedUsersLong += buildContactLink(this.assetData.markers[i].MarkedUserAoMURL, this.assetData.markers[i].MarkedUserName);
      }
      ageElements.push({
        id: this.assetData.markers[i].MarkedUserID,
        value: this.assetData.markers[i].MarkedUserName
      });
    }
  }
  $get("AssetPage_person_markers_control_closed").innerHTML = markedUsersShort;
  $get("AssetPage_person_markers_control").innerHTML = markedUsersLong;
  if (ageElements.length) {
    $get("AssetPage_time_stamp_change_age_container").style.color = "#000000";
    $get("AssetPage_time_stamp_change_age_name").disabled = false;
    $get("AssetPage_time_stamp_change_age_number").disabled = false;
    var nameSelect = '\
      <select id="AssetPage_time_stamp_change_age_name"\
      onchange="assetPage.markedUserNameSelected(this.value)">';
    nameSelect += createPropListOptions(ageElements, ageElements[0].id) + "</select>";
    $get("AssetPage_time_stamp_change_age_name").parentNode.innerHTML = nameSelect;
    this.markedUserNameSelected(ageElements[0].id);
  } else {
    $get("AssetPage_time_stamp_change_age_container").style.color = "#999999";
    $get("AssetPage_time_stamp_change_age_name").disabled = true;
    $get("AssetPage_time_stamp_change_age_number").disabled = true;
    $get("AssetPage_time_stamp_change_age_name").innerHTML = "";
    $get("AssetPage_time_stamp_change_age_number").innerHTML = "";
  }
  this.controls.person_markers.close();
  this.controls.person_markers.enable(this.assetData.markers.length);
}

AssetPage.prototype.markedUserNameSelected = function(userID) {
  var age = bodToAge(userID, new Date());
  var ageInAsset = bodToAge(userID, this.assetDate.date);
  var ageSelect = '\
      <select id="AssetPage_time_stamp_change_age_number"\
      onchange="assetPage.markedUserAgeSelected($get(\'AssetPage_time_stamp_change_age_name\').value, this.value)">';
  ageSelect +=  createRangeOptions(1, age, ageInAsset, false) + "</select>";
  $get("AssetPage_time_stamp_change_age_number").parentNode.innerHTML = ageSelect;
}

AssetPage.prototype.markedUserAgeSelected = function(userID, age) {
  var birthDate = birthDateToDate(ContactCloud[userID].BirthDate);
  birthDate.setFullYear(birthDate.getFullYear() + new Number(age));
  this.controls.time_stamp.specialFunction("update", { from: "age", date: birthDate });
}

AssetPage.prototype.setAgeDate = function(curDate) {
  var userID = $get("AssetPage_time_stamp_change_age_name").value;
  if (userID != "") {
    var birthDate = birthDateToDate(ContactCloud[userID].BirthDate);
    var dif = curDate.getFullYear() - birthDate.getFullYear();
    if (curDate.getMonth() < birthDate.getMonth()) {
      dif -= 1;
    } else if (curDate.getMonth() == birthDate.getMonth()) {
      if (curDate.getDate() < birthDate.getDate()) {
        dif -= 1;
      }
    }
    if (dif > 0)
    $get("AssetPage_time_stamp_change_age_number").value = dif;
  }
}

// set controls and Comments set [end]

AssetPage.prototype.resetControls = function() {
    this.controls = new Object();
    this.controls.share = new AssetPageControl(this, "share");
    this.controls.tag = new AssetPageControl(this, "tag");
    this.controls.person_markers = new AssetPageControl(this, "person_markers");
    this.controls.time_stamp = new AssetPageControl(this, "time_stamp");
}

AssetPage.prototype.fillTagList = function() {
  //if (assetPageUserTags == "object") return;
  var tagBranch, i, j;

  tagBranch = 0;
  // find the Tag cache object	
  for (i = 0, j = cacheBranches.length; i < j; i++) {
      if (cacheBranches[i].BranchType == BranchTypes.TAG) {
          tagBranch = cacheBranches[i];
          break;
      }
  }
  /*
  // removed for the time being
  if (tagBranch == 0) {
      // no tags in cache yet:
      executeWebRequest("Sidebar.GetTags", [{ name: "SerType", value: 2 }, { name: "Skip", value: 0 }, { name: "Take", value: Consts.LOAD_AMOUNT}], { onSuccessFunction: assetPageCB.userTagsOnSuccess, onFailureFunction: assetPageCB.fail });
      return;
  }
  // else, if no tags are loaded into cache - load some - try until we get something:
  if (tagBranch.Children.length == 0) {
      if (!tagBranch.IsFull && !tagBranch.IsLoading) {
          setTimeout(ContextDelegate(this, this.fillTagList), 500);
          tagBranch.prefetchData();
          return;
      }
  } else {
      this.necessaryDataLoaded.UserTagsFetched = true;
      this.controls.tag.specialFunction("construct_user_tags", tagBranch);
  }
  this.necessaryDataLoaded.UserTagsFetched = true;
  */
}

// -- AssetPage callbacks [start]

AssetPage.prototype.balloonMaximized = function(controlToOpen) {
this.controlToOpen = controlToOpen;
  this.necessaryDataLoaded.BalloonOpened = true;
  //flash.assetPageIsReady();
}

AssetPage.prototype.updateAssetPage = function() {
  this.message.stopProcessing(true);
  $get("AssetPage_sub_container").style.display = "block";
}

AssetPage.prototype.minimize = function() {
  this.prepareClosing();
  setTimeout("flash.assetPageMinimized()", 100);
}

AssetPage.prototype.close = function(immidiately) {
  this.prepareClosing();
  setTimeout("flash.assetPageClosed()", 100);
}

AssetPage.prototype.prepareClosing = function() {
  for (var id in this.queueDateChanges) {
    flash.assetChangeDate(this.queueDateChanges[id].flashAsset, this.queueDateChanges[id].date);
  }
  flash.setApplicationMode("normal");
  setTimeout(setViewToTimeline, 50);
}

function setViewToTimeline() {
  pageView.setView("TIMELINE");
}

AssetPage.prototype.idleView = function() {
  for (var props in this.controls) {
    this.controls[props].close();
  }
  this.resetControls();
  this.necessaryDataLoaded.AssetData = false;
  //this.necessaryDataLoaded.UserTagsFetched = false;
  clearInterval(this.loadInterval);
  this.loadInterval = 0;
  try{
    $get("AssetPage_tbTagName").disabled = false;
    $get("AssetPage_comment_textarea").value = "";
    $get("AssetPage_asset_title_editor").style.display = "none";
    $get("AssetPage_asset_title").style.display = "none";
    $get("AssetPage_album_asset_title_container1").style.display = "none";
    $get("AssetPage_album_asset_title_container2").style.display = "none";
    $get("AssetPage_description_edit").style.visibility = "hidden";
    $get("AssetPage_description_editor").style.display = "none";
    $get("AssetPage_description_text").style.display = "block";
    $get("AssetPage_time_stamp_change_age_container").style.color = "#999999";
    $get("AssetPage_time_stamp_change_age_name").disabled = true;
    $get("AssetPage_time_stamp_change_age_number").disabled = true;
    $get("AssetPage_time_stamp_change_age_name").innerHTML = "";
    $get("AssetPage_time_stamp_change_age_number").innerHTML = "";
    $get("AssetPage_AomType_title").innerHTML = "";
    $get("AssetPage_description_text").innerHTML = "";
    $get("AssetPage_album_asset_parent_title").innerHTML = "";
    $get("AssetPage_album_asset_title").innerHTML = "";
    $get("AssetPage_asset_in_album").innerHTML = "";
    $get("AssetPage_asset_title").innerHTML = "";
    $get("AssetPage_first_brought_name").innerHTML = "";
    $get("AssetPage_num_views").innerHTML = "0";
    $get("AssetPage_comments_container").innerHTML = "";
    if (this.message != undefined)
      this.message.setTemplateMessage("processing");
  } catch (e) { }
  try {
    if (this.starsController != undefined)
    this.starsController.idleView();
  } catch (e) { }
  try {
    this.message.idleView();
  } catch (e) { }
  try {
    if (this.player != undefined)
      this.player.idleView();
  } catch (e) { }
  markerController.init();
}

AssetPage.prototype.hide = function() {
  //$get("AssetPage_container").style.visibility = "hidden";  
  $get("AssetPage_container").style.display = "none";
  $get("AssetPage_under_top_strip").style.display = "none";
  this.message.hide();
  $get("searchBlock").style.display = "block";
  this.idleView();
}

AssetPage.prototype.show = function() {
  this.idleView();
  this.message.setMessage("Opening Asset, please wait", true, false);
  $get("AssetPage_under_top_strip").style.display = "block";
  $get("searchBlock").style.display = "none";
  $get("AssetPage_container").style.display = "block";
}

AssetPage.prototype.setHeight = function(newHeight) {
    if ($get("AssetPage_container").style.display == "block") {
        newHeight -= assetPageConsts.BOTTOM_SHORT - sizeConsts.UNDER_TOP_STRIP_HEIGHT;
        $get("AssetPage_container").style.height = newHeight + "px";
    }
}

AssetPage.prototype.navigateAsset = function(assetObject, navigationType) {
  if (typeof (navigationType) == "undefined") navigationType = "Navigation";
  this.flashAsset = assetObject;
  this.history[this.flashAsset.ID] = {
    navigationType: navigationType,
    flashAsset: assetObject
  }
  setTimeout(ContextDelegate(this, this.continueNavigation), 100);
}

AssetPage.prototype.continueNavigation = function() {
  //if (this.flashAsset.ID == undefined) debugger;
  var navObj = this.history[this.flashAsset.ID];
  Sys.Application.addHistoryPoint({ NavigationMode: "AssetPage", NavigationType: navObj.navigationType, AssetID: navObj.flashAsset.ID });
}

AssetPage.prototype.completeNavigation = function(navigationType, assetID) {
    var currentAsset = this.flashAsset;
    if (currentAsset.ID != assetID) {
        // loading from history:
        // Oded: check if there's something in the histroy (if the user clicked F5 in the asset page it clears the history!)
        var histroyPoint = this.history[assetID];
        if (histroyPoint != undefined) {
            var nextAsset = histroyPoint.flashAsset;
            this.flashAsset = nextAsset;
            switch (navigationType) {
                case "AlbumNavigation":
                    if (currentAsset.Type == "Asset" && nextAsset.Type == "Asset")
                        flash.assetPageSelectAssetInAlbum(currentAsset.ID, this.parentAlbum.ID, this.assetData.TimelineID);
                    break;
                case "Navigation":
                    if (currentAsset.Type == "Asset" && nextAsset.Type == "Album")
                        this.backToAlbum();
                    else
                        flash.assetPageSelectAsset(assetID, currentAsset.TimelineID);
                    break;
            }
        }
    }
    this.idleView();
    var navMode = (navigationType == "AlbumNavigation") ? assetPageConsts.ASSET_IN_ALBUM : assetPageConsts.ASSET;
    this.prepareContents(navigationType, navMode);
}

AssetPage.prototype.editDescription = function() {
    $get("AssetPage_description_textarea").value = this.assetData.Description;
    $get("AssetPage_description_text").style.display = "none";
    $get("AssetPage_description_editor").style.display = "block";
    $get("AssetPage_description_edit").style.visibility = "hidden";
    $get("AssetPage_description_textarea").focus();
}

AssetPage.prototype.closeDescriptionEditor = function(fail) {
    if (fail) this.state = 0;
    $get("AssetPage_description_text").style.display = "block";
    $get("AssetPage_description_editor").style.display = "none";
    $get("AssetPage_description_edit").style.visibility = "visible";
}

AssetPage.prototype.descriptionEdited = function() {
  if (this.state == 1) return;
  this.state = 1;

  var newDesc = $get("AssetPage_description_textarea").value;
  newDesc = ReplaceAll(newDesc, "&", "[_amp_]");

  this.message.setTemplateMessage("processing");
  pendingAction.functionName = "Assets.ChangeDescription";
  pendingAction.functionParams = new Array(
    { name: "AssetID", value: this.assetData.ID },
    { name: "Desc", value: escape(newDesc) },
    { name: "SerType", value: "2" });
  pendingAction.callbackData = { onSuccessFunction: ContextDelegate(this, this.descriptionSetSuccess), onFailureFunction: assetPageCB.fail, action: "set_description" };
  executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
}

AssetPage.prototype.aomTypeClicked = function() {
  if (this.flashAsset.Type != "Album") {
    if (this.assetData.OriginURL != null) {
      if (this.assetData.OriginURL.indexOf("http://") == 0) {
        window.open(this.assetData.OriginURL);
      }
    }
  }
}

AssetPage.prototype.descriptionSetSuccess = function() {
    this.state = 0;
    //enableButton("AssetPage_description_done", true);
    EnableChangeDescBtn();
    this.assetData.Description = $get("AssetPage_description_textarea").value;
    $get("AssetPage_description_text").innerHTML = this.assetData.Description;
    if (this.assetData.Description == "") {
      $get("AssetPage_description_edit").innerHTML = "Write description";
    } else {
      $get("AssetPage_description_edit").innerHTML = "Edit description";
    }
    this.closeDescriptionEditor();
    this.message.setTemplateMessage("done");
}

AssetPage.prototype.titleMouseOver = function() {
    if (!this.assetData.CanChangeTexts) return;
    if ($get("AssetPage_asset_title_editor").style.display == "block") return;
    var activeTitle = this.getActiveTitle();
    activeTitle.style.background = "#ffffd3";
    if (this.titleBgTimeout != 0) {
        clearTimeout(this.titleBgTimeout);
        this.titleBgTimeout = 0;
    }
}

AssetPage.prototype.titleMouseOut = function() {
    if (!this.assetData.CanChangeTexts) return;
    this.titleBgTimeout = setTimeout(ContextDelegate(this, this.resetTitleBackground), 1000);
}

AssetPage.prototype.resetTitleBackground = function() {
    if (!this.assetData.CanChangeTexts) return;
    var activeTitle = this.getActiveTitle();
    activeTitle.style.background = "";
    clearTimeout(this.titleBgTimeout);
    this.titleBgTimeout = 0;
}

AssetPage.prototype.editTitle = function() {
  if (!this.assetData.CanChangeTexts) return;
  if ($get("AssetPage_asset_title_editor").style.display == "block") return;
  this.resetTitleBackground();
  $get("AssetPage_asset_title_input").value = this.assetData.Title;
  $get("AssetPage_asset_title_editor").style.display = "block";
  $get("AssetPage_asset_title").style.display = "none";
}

AssetPage.prototype.getActiveTitle = function() {
  if (this.viewMode == assetPageConsts.ASSET_IN_ALBUM)
    return $get("AssetPage_album_asset_title");
  else
    return $get("AssetPage_asset_title");
}

AssetPage.prototype.closeTitleEditor = function() {
  $get("AssetPage_asset_title_editor").style.display = "none";
  switch (this.viewMode) {
    case assetPageConsts.ASSET:
    case assetPageConsts.ALBUM:
      $get("AssetPage_asset_title").style.display = "block";
    case assetPageConsts.ASSET_IN_ALBUM:
      $get("AssetPage_album_asset_title").style.display = "block";
  }
}

AssetPage.prototype.titleEdited = function() {
  if (this.state == 2) return;
  this.state = 2;
  //enableButton("AssetPage_asset_title_done", false);
  this.message.setTemplateMessage("processing");
  var newTitle = $get("AssetPage_asset_title_input").value
  newTitle = ReplaceAll(newTitle, "&", "[_amp_]")
  switch (this.viewMode) {
    case assetPageConsts.ASSET_IN_ALBUM:
    case assetPageConsts.ASSET:
      pendingAction.functionName = "Assets.ChangeTitle";
      pendingAction.functionParams = new Array(
            { name: "AssetID", value: this.assetData.ID },
            { name: "Title", value: escape(newTitle) },
            { name: "SerType", value: "2" });
      break;
    case assetPageConsts.ALBUM:
      pendingAction.functionName = "Albums.Rename";
      pendingAction.functionParams = new Array(
            { name: "AlbumID", value: this.assetData.ID },
            { name: "NewTitle", value: escape(newTitle) },
            { name: "SerType", value: "2" });
      break;
  }
  pendingAction.callbackData = { onSuccessFunction: ContextDelegate(this, this.titleSetSuccess), onFailureFunction: assetPageCB.fail, action: "set_title" };
  executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
}

AssetPage.prototype.titleSetSuccess = function() {
  this.message.setTemplateMessage("done");
  this.state = 0;
  EnableChangeTitleBtn();
  this.assetData.Title = $get("AssetPage_asset_title_input").value;
  var activeTitle = this.getActiveTitle();
  activeTitle.innerHTML = this.assetData.Title;

  flash.renameAsset(this.flashAsset, this.assetData.Title);
  this.closeTitleEditor();
}

AssetPage.prototype.backToAlbum = function() {
  this.flashAsset = this.parentAlbum;
  this.idleView();
  $get("AssetPage_album_asset_title_container1").style.display = "none";
  $get("AssetPage_album_asset_title_container2").style.display = "none";
  flash.assetPageSelectAsset(this.parentAlbum.ID, this.parentAlbum.TimelineID);
  this.prepareContents("Navigation", assetPageConsts.ALBUM);
}

AssetPage.prototype.pageMouseUp = function(e) {
  this.timeSlider.timeStampStopDrag();
  if (($get("AssetPage_navigation_dropdown").style.display == "block") && !assetPageDropdownTimeout)
    assetPageHideNavigationDropdown();
}

AssetPage.prototype.enableAddPersonMarkers = function() {
  if (this.assetData.CanAddMarker) {
    $get("AssetPage_add_person_marker").className = "AssetPage_float_left AssetPage_action"
    $get("AssetPage_add_person_marker").style.backgroundImage = "url(/Images/AssetPage/person_marker_icon.png)";
    $get("AssetPage_add_person_marker").onclick = function(e) { markerController.addDefaultMarker('person') };
  } else {
    this.disablePersonMarkers();
  }
}

AssetPage.prototype.enableAddImageNotes = function() {
  $get("AssetPage_add_image_note").className = "AssetPage_float_left AssetPage_action_disabled"
  $get("AssetPage_add_image_note").style.backgroundImage = "url(/Images/AssetPage/image_note_icon_dis.gif)";
  $get("AssetPage_add_image_note").onclick = null;
}

AssetPage.prototype.shareSelectionChanged = function(checked, selectionType) {
    var checkboxElements = document.getElementsByName("AssetPage_ShareWith");
    if (checked) {
        for (var i = 0; i < checkboxElements.length; i++) {
            switch (selectionType) {
                case "everyone":
                    checkboxElements[i].checked = true;
                    break;
                case "network":
                    checkboxElements[i].checked = (i > 0);
                    break;
                case "none":
                    checkboxElements[i].checked = false;
                    break;
            }
        }
        if (selectionType == "none") this.controls.share.done();
    } else {
        switch (selectionType) {
            case "group":
                checkboxElements[1].checked = false; // no 'break;' here - also unchecking network
            case "network":
                checkboxElements[0].checked = false;
                break;
        }
    }
}

AssetPage.prototype.keypressedAction = function(e, submitElement, onEscAction) {
  var keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
  //AssetPage_add_new_tag_submit add_tag
  switch (keyCode) {
    case 13: // enter
      switch (submitElement) {
        case "title":
          this.titleEdited();
          return false;
        case "add_tag":
          this.controls.tag.specialFunction('add_tag');
          return false;
      }
      return true;
    case 27: // esc
      eval(onEscAction);
      return false;
      break;
    default:
      return true;
  }
}

AssetPage.prototype.markerUpdated = function(updateType, markerData) {
  var markerIndex = -1;
  for (var i = 0; i < this.assetData.markers.length; i++) {
    if (this.assetData.markers[i].ID == markerData.id) {
      markerIndex = i;
      break;
    }
  }
  switch (updateType) {
    case 'new':
      markerData.Note = markerData.MarkedUserName = "";
      if (markerData.MarkedUserID == 0)
        markerData.Note = markerData.Note;
      else
        markerData.MarkedUserName = ContactCloud[markerData.MarkedUserID].Name;
      this.assetData.markers.push(markerData);
      break;
    case 'update':
      if (markerIndex > -1) {
        this.assetData.markers[markerIndex].MarkedUserID = markerData.MarkedUserID;
        this.assetData.markers[markerIndex].MarkedUserName = ContactCloud[this.assetData.markers[markerIndex].MarkedUserID].Name;
        this.assetData.markers[markerIndex].Note = markerData.Note;
      }
      break;
    case 'delete':
      this.assetData.markers.splice(markerIndex, 1);
      break;
  }
  this.setMarkerElements();
}

AssetPage.prototype.disablePersonMarkers = function() {
  $get("AssetPage_add_person_marker").className = "AssetPage_float_left AssetPage_action_disabled"
  $get("AssetPage_add_person_marker").style.backgroundImage = "url(/Images/AssetPage/person_marker_icon_dis.png)";
  $get("AssetPage_add_person_marker").onclick = null;
}

// -- AssetPage callbacks [end]

// AssetPage class [end]

// Data parsers [start]

function AssetPageCB() {
}

AssetPageCB.prototype.getAssetDetails = function(recievedData, callbackData) {
  assetPage.assetData = recievedData;
  assetPage.necessaryDataLoaded.AssetData = true;
}
/*
AssetPageCB.prototype.userTagsOnSuccess = function(recievedData, callbackData) {
    assetPage.necessaryDataLoaded.UserTagsFetched = true;
    assetPage.controls.tag.specialFunction("construct_user_tags", recievedData);
}
*/

AssetPageCB.prototype.postComments = function(recievedData, callbackData) {
  assetPage.message.setTemplateMessage("done");
  EnablePostCommentBtn();
  $get("AssetPage_comment_textarea").value = "";
  assetPage.comments.addComment(recievedData);
  assetPage.comments.AddCommentState = false;
  $get("AssetPage_comments_container").innerHTML = assetPage.comments.getHtml();
}

AssetPageCB.prototype.editComments = function(recievedData, callbackData) {
  assetPage.message.setTemplateMessage("done");
  assetPage.comments.commentAction(callbackData.CommentID, 'edited');
}

AssetPageCB.prototype.deleteComment = function(receivedData, callbackData) {
  assetPage.message.setTemplateMessage("done");
  assetPage.comments.commentAction(callbackData.CommentID, 'deleted');
}

AssetPageCB.prototype.deleteTagOnSuccess = function(receivedData, callbackData) {
  assetPage.message.setTemplateMessage("done");
  var tagsHtml, i, j;
  delete (assetPage.assetData.tags[callbackData.tagID]);
  tagsHtml = shortTagsHtml = "";
  j = 0;
  for (i in assetPage.assetData.tags) {
      tagsHtml += getTagListLine(assetPage.assetData.tags[i]);
      if (j++ < 6) {
          if (j++ > 0) shortTagsHtml += " ";
          shortTagsHtml += assetPage.assetData.tags[i].Title;
      }
  }
  $get("AssetPage_tag_control_list").innerHTML = tagsHtml;
  $get("AssetPage_tag_control_closed").innerHTML = shortTagsHtml;
}

AssetPageCB.prototype.addTagsOnSuccess = function(receivedData, callbackData) {
  assetPage.message.setTemplateMessage("done");
  assetPage.controls.tag.specialFunction('update_tags', receivedData);
}

AssetPageCB.prototype.changeDate = function(recievedData, callbackData) {
  assetPage.message.setTemplateMessage("done");
  //enableButton("AssetPage_time_stamp_change_done", true);
  EnableChangeTimestampBtn();
  assetPage.controls.time_stamp.close();
}

AssetPageCB.prototype.rating = function(recievedData, callbackData) {
  assetPage.message.setMessage("Thanks for your rating", false, true);
  assetPage.starsController.ratingComplete(recievedData);
}

AssetPageCB.prototype.fail = function(callbackData) {
  assetPage.message.setMessage("Oops... could not complete task", false, true, true);
  switch (callbackData.action) {
      case "post_comment":
          EnablePostCommentBtn();
          $get("AssetPage_comment_textarea").value = "";
          break;
      case "set_description":
          EnableChangeDescBtn();
          assetPage.closeDescriptionEditor(true);
          break;
      case "set_title":
          EnableChangeTitleBtn();
          assetPage.closeTitleEditor(true);
          break;
  }
}

// data parsers [end]

// controls [start]

function AssetPageControl(containerObject, controlName) {
    this.container = containerObject;
    this.parent = $get("AssetPage_" + controlName);
    this.header = $get("AssetPage_" + controlName + "_head");
    this.control = $get("AssetPage_" + controlName + "_control");
    this.edit = $get("AssetPage_" + controlName + "_edit");
    this.icon = $get("AssetPage_" + controlName + "_icon");
    this.botBorder = $get("AssetPage_" + controlName + "_bottomborder");
    this.controlClosed = $get("AssetPage_" + controlName + "_control_closed").parentNode;
    this.controlName = controlName;
    this.defaultClass = this.parent.className;
    this.isOpen = false;
    this.edit.style.display = "none";
    disableSelection(this.header);
    this.isLoaded = false;
    this.header.style.color = "#999999";
    this.header.style.backgroundImage = "url(/Images/Sidebar/arw_right_dis.png)";
    this.icon.className = "AssetPage_right_icon AssetPage_" + controlName + "_icon_disabled";
    this.controlClosed.style.display = "none";
    this.canEdit = true;
}

AssetPageControl.prototype.enable = function(canEdit) {
  this.icon.className = "AssetPage_right_icon AssetPage_" + this.controlName + "_icon";
  this.controlClosed.style.display = "block";
  this.isLoaded = true;
  if (canEdit) {
    this.header.style.color = "#000000";
    this.header.style.backgroundImage = "url('/Images/Sidebar/arw_right.png')";
    this.icon.className = "AssetPage_right_icon AssetPage_" + this.controlName + "_icon";
    this.edit.style.display = "block";
    this.header.style.cursor = "pointer";
    this.controlClosed.style.cursor = "pointer";
    this.canEdit = true;
  } else {
    this.header.style.color = "#999999";
    this.header.style.cursor = "default";
    this.controlClosed.style.cursor = "default";
    this.icon.className = "AssetPage_right_icon AssetPage_" + this.controlName + "_icon_disabled";
    this.header.style.backgroundImage = "url('/Images/Sidebar/arw_right_dis.png')";
    this.edit.style.display = "none";
    this.canEdit = false;
  }
  if (this.controlName == "time_stamp") {
    $get("AssetPage_time_stamp_control_closed").style.color = canEdit ? "#000000" : "#999999";
  }
}

AssetPageControl.prototype.removeWaitingAnim = function() {
    this.parent.style.background = "white";
}

AssetPageControl.prototype.open = function() {
    if (!this.isLoaded) return;
    if (!this.canEdit) return;
    if (this.isOpen) {
        this.close();
        return;
    }
    this.isOpen = true;
    this.header.style.backgroundImage = "url('/Images/Sidebar/arw_dwn.png')";
    this.control.style.display = "block";
    this.controlClosed.style.display = "none";
    switch (this.controlName) {
        case "time_stamp":
            this.container.timeSlider.setPosition();
            $get("AssetPage_date_change").style.display = "none";
            break;
    }
}

AssetPageControl.prototype.close = function() {
  this.isOpen = false;
  this.header.style.backgroundImage = "url('/Images/Sidebar/arw_right.png')";
  this.control.style.display = "none";
  this.controlClosed.style.display = "block";
  switch (this.controlName) {
    case "time_stamp":
      $get("AssetPage_date_change").style.display = this.container.assetData.CanChangeDate ? "block" : "none";
      break;
  }
}

AssetPageControl.prototype.done = function() {
    switch (this.controlName) {
        case "share":
            var removeList = "";
            var addList = "";
            var i, j, isAlreadyShared, sharedId;
            var contactElements = document.getElementsByName("AssetPage_ShareWith");
            var params;
            for (i = 0; i < contactElements.length; i++) {
                isAlreadyShared = false;
                sharedId = parseInt(contactElements[i].getAttribute('id').split('_')[1]);
                for (j in this.container.assetData.shareGroups) {
                    if (this.container.assetData.shareGroups[j] == sharedId) {
                        isAlreadyShared = true;
                        break;
                    }
                }
                if (contactElements[i].checked && !isAlreadyShared)
                    addList += sharedId + ",";
                else if (!contactElements[i].checked && isAlreadyShared)
                    removeList += sharedId + ",";
            }
            assetPageApiQueue.init(AssetPageCompleteShareChanges);
            if (removeList != "") {
                // need to remove targets from share first
                removeList = removeList.substring(0, removeList.length - 1);
                params = [{ name: "SerType", value: 2 }, { name: "EntityIDs", value: this.container.assetData.ID }, { name: "TargetIDs", value: removeList}];
                assetPageApiQueue.addToQueue("Sharing.UnshareEntities", params);
            }
            if (addList != "") {
                // but there are new share targets
                addList = addList.substring(0, addList.length - 1);
                params = [{ name: "Owner", value: this.container.flashAsset.OwnerID }, { name: "SerType", value: 2 }, { name: "EntityIDs", value: this.container.assetData.ID }, { name: "TargetIDs", value: addList}];
                assetPageApiQueue.addToQueue("Sharing.SimplyShareEntities", params)
            }
            if ((addList != "") || (removeList != "")) {
                //enableButton("AssetPage_share_ok", false);
                assetPageApiQueue.start();
            }
            break;
        case "time_stamp":
            var selectedDate = this.container.controls.time_stamp.specialFunction("get_selected_date");
            var selectedDateObject = new AssetPageDate(selectedDate, this.container.assetData.Precision, "date");
            var formattedDate = selectedDateObject.getFormattedDate(assetPageConsts.DATE_TIME_2);
            this.container.message.setTemplateMessage("processing");
            pendingAction.functionName = "Assets.ChangeDate";
            //enableButton("AssetPage_time_stamp_change_done", false);
            pendingAction.functionParams = new Array(
            { name: "AssetID", value: this.container.assetData.ID },
            { name: "NewDate", value: formattedDate },
            { name: "DatePrecision", value: this.container.assetData.Precision },
            { name: "SerType", value: "2" });
            pendingAction.callbackData = { onSuccessFunction: assetPageCB.changeDate, onFailureFunction: assetPageCB.generalFail, action: "set_title" };
            executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
            this.container.assetDate.update(selectedDate);
            this.container.queueDateChanges[this.container.flashAsset.ID] = { flashAsset: AssetPageClone(this.container.flashAsset), date: selectedDateObject.getFormattedDate(assetPageConsts.FLASH_DATE) };
            break;
    }
}

AssetPageControl.prototype.specialFunction = function(functionName, params) {
  switch (this.controlName) {
    case "tag":
      switch (functionName) {
        case "delete_tag":
          pendingAction.pending = true;
          pendingAction.numOfRetries = 0;
          // display the processing action wait window until done processing
          this.container.message.setTemplateMessage("processing");
          pendingAction.functionName = "Tags.RemoveTagFromEntities";
          pendingAction.functionParams = [{ name: "SerType", value: 2 }, { name: "EntityIDs", value: this.container.assetData.ID }, { name: "TagID", value: params}];
          pendingAction.callbackData = { onSuccessFunction: assetPageCB.deleteTagOnSuccess, onFailureFunction: assetPageCB.generalFail, action: "delete_tag", tagID: params };
          executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
          break;
        case "add_tag":
          var chosenTags = AssetPageParseChosenTags();
          var chosenTagsString = chosenTags.join(',');
          $get("AssetPage_tbTagName").disabled = true;
          pendingAction.pending = true;
          pendingAction.numOfRetries = 0;
          this.container.message.setTemplateMessage("processing");
          // display the processing action wait window until done processing
          pendingAction.functionName = "Tags.AddTagsToEntities";
          pendingAction.functionParams = [
            { name: "Owner", value: this.container.flashAsset.OwnerID },
            { name: "SerType", value: 2 },
            { name: "EntityIDs", value: this.container.assetData.ID },
            { name: "TagTexts", value: chosenTagsString}];
          pendingAction.callbackData = { onSuccessFunction: assetPageCB.addTagsOnSuccess, onFailureFunction: assetPageCB.generalFail, action: "add_tag", tagID: params };
          executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
          break;
        case "update_tags":
          $get("AssetPage_tbTagName").disabled = false;
          $get("AssetPage_tbTagName").value = "";
          if ($get("AssetPage_tag_control_current_tags").innerHTML == "") {
            $get("AssetPage_tag_control_current_tags").innerHTML = '\
      <div class="HeaderText">Current Tags:</div>\
      <div id="AssetPage_tag_control_list"></div>\
      </div>\
      <div class="hr"></div>';
          }
          var tagsHtml = $get("AssetPage_tag_control_list").innerHTML;
          shortTagsHtml = "";
          for (var i = 0; i < params.length; i++) {
            if (typeof (this.container.assetData.tags[params[i].ID]) == "undefined") {
              params[i].CanDelete = true;
              this.container.assetData.tags[params[i].ID] = params[i];
              // tag does not exist yet
              tagsHtml += getTagListLine(params[i]);
            }
            if (i < 6) {
              if (i > 0) shortTagsHtml += " ";
              shortTagsHtml += params[i].Title;
            }
          }
          $get("AssetPage_tag_control_list").innerHTML = tagsHtml;
          $get("AssetPage_tag_control_closed").innerHTML = shortTagsHtml;
          break;
        case "construct_user_tags":
          assetPageUserTags = new Array();
          for (var i = 0; i < params.length; i++) {
            assetPageUserTags["" + params[i].ID] = params[i].Title;
          }
          break;
      }
      break;
    case "time_stamp":
      var selectedDate;
      switch (functionName) {
        case "reset":
          if (this.tempDate != undefined) {
            this.container.assetDate.date = new Date();
            this.container.assetDate.date.setTime(this.tempDate.valueOf());
            this.container.assetData.Precision = this.tempPrecision;
          }
          this.container.setTime(this.container.assetDate.date);
          this.container.setAgeDate(this.container.assetDate.date);
          this.container.timeSlider.setPosition(this.container.assetDate.date);
          this.close();
          break;
        case "update":
          var selectedDate;
          if (this.tempDate == undefined) {
            this.tempDate = new Date();
            this.tempDate.setTime(this.container.assetDate.date.valueOf());
            this.tempPrecision = this.container.assetData.Precision;
          }
          switch (params.from) {
            case "selection":
              if ($get("AssetPage_time_stamp_change_" + params.control).value == "--") {
                for (var i = 0; i < datePrecisionsEnum.length; i++) {
                  if (datePrecisionsEnum[i] == params.control) {
                    this.container.assetData.Precision = dateReversePrecisions[datePrecisionsEnum[i + 1]];
                    break;
                  }
                }
              } else if (dateReversePrecisions[params.control] < this.container.assetData.Precision) {
                this.container.assetData.Precision = dateReversePrecisions[params.control];
              }
              selectedDate = this.container.controls.time_stamp.specialFunction("get_selected_date", params);
              this.container.timeSlider.setPosition(selectedDate);
              this.container.setAgeDate(selectedDate);
              this.container.setTime(selectedDate);
              break;
            case "slider":
              selectedDate = params.date;
              this.container.assetData.Precision = datePrecisions.YEAR;
              this.container.setTime(params.date);
              this.container.setAgeDate(params.date);
              break;
            case "age":
              selectedDate = params.date;
              this.container.assetData.Precision = datePrecisions.DAY;
              this.container.setTime(params.date);
              this.container.timeSlider.setPosition(this.container.controls.time_stamp.specialFunction("get_selected_date"));
              break;
          }
          this.container.assetDate.date.setTime(selectedDate.valueOf());
          break;
        case "get_selected_date":
          var curDate = new Date();
          var controlType, curValue;
          curDate.setFullYear(parseInt($get("AssetPage_time_stamp_change_year").value));
          curDate.setMonth(6);
          curDate.setDate(Math.ceil(getDaysInMonth(curDate) / 2));
          curDate.setHours(12);
          curDate.setMinutes(0);
          curDate.setSeconds(0);
          curDate.setMilliseconds(0);

          for (controlType in dateReversePrecisions) {
            curValue = $get("AssetPage_time_stamp_change_" + controlType).value;
            if (this.container.assetData.Precision <= dateReversePrecisions[controlType]) {
              if (curValue == "--") {
                switch (controlType) {
                  case "minute": newValue = curDate.getMinutes(); break;
                  case "hour": newValue = curDate.getHours(); break;
                  case "date": newValue = curDate.getDate(); break;
                  case "month":
                    var shortMonths = AssetPageGetShortMonths();
                    newValue = shortMonths[curDate.getMonth()];
                    break;
                }
                $get("AssetPage_time_stamp_change_" + controlType).value = newValue;
              } else {
                switch (controlType) {
                  case "minute": curDate.setMinutes(curValue); break;
                  case "hour": curDate.setHours(curValue); break;
                  case "date": curDate.setDate(curValue); break;
                  case "month": curDate.setMonth(curValue); break;
                }
              }
            } else {
              $get("AssetPage_time_stamp_change_" + controlType).value = "--";
            }
          }
          return curDate;
      }
  }
}

// controls [end]

// Timestamp drag [start]

function AssetPageTimestampSlider(container) {
    this.container = container;
    this.timestampDragging = false;
    this.pixelsToLeft = 0;
    this.sliderPosition = 0;
    this.stripWidth = 2633;
    this.sliderBoxWidth = 0;
    this.offsetAtClick = 0;
    this.shiftSliderTimeout = 0;
    this.shiftSide = "";
    this.shiftSpeed = 0;
}

AssetPageTimestampSlider.prototype.setPosition = function(curDate) {
    var sliderBoxWidth, curYear, pixelDelta, stripPosition;
    if (typeof (curDate) == "undefined") curDate = this.container.assetDate.date;
    curYear = curDate.getFullYear();
    // 1500 = 16 pixels to the left
    // each century is 50 pixels (1 year = 5 pixels)
    // total strip width is 2633
    this.sliderBoxWidth = $get("AssetPage_time_stamp_change_slider_box").offsetWidth;
    if ((curYear >= 1500) && (curYear <= 2020)) {
        this.pixelsToLeft = (curYear - 1500) * 5 + Math.round((curDate.getMonth() + 1) / 12 * 5) + 16;
        // trying to put current year in the center of the box:
        pixelDelta = this.stripWidth - this.pixelsToLeft;
        if (this.pixelsToLeft <= this.sliderBoxWidth) {
            this.pixelsToLeft = 0;
        } else if (pixelDelta > this.sliderBoxWidth / 2) {
            // okay:
            this.pixelsToLeft -= Math.round(this.sliderBoxWidth / 2);
        } else {
            this.pixelsToLeft = this.stripWidth - this.sliderBoxWidth;
        }
        $get("AssetPage_time_stamp_change_slider_timeline").style.backgroundPosition = "-" + this.pixelsToLeft + "px 0px";

        // calculating the slider position over the entire strip:
        this.sliderPosition = (curYear - 1500) * 5 + 8;
        this.sliderPosition += Math.round(getDayInYear(curDate) / 365 * 5);
        this.sliderPosition -= this.pixelsToLeft;
        $get("AssetPage_time_stamp_change_slider").style.marginLeft = this.sliderPosition + "px";
    }
}

AssetPageTimestampSlider.prototype.timeStampStartDrag = function() {
    this.offsetAtClick = tempX - getElementAbsoluteX("AssetPage_time_stamp_change_slider");
    $get("AssetPage_time_stamp_change_slider").style.backgroundImage = "url('/Images/AssetPage/timestamp_slider_transparent.png')";
    enableDragSelect(true);
    this.timestampDragging = true;
}

AssetPageTimestampSlider.prototype.timestampDrag = function() {
    if (this.timestampDragging) {
        var minLeft = getElementAbsoluteX("AssetPage_time_stamp_change_slider_box");
        var maxRight = minLeft + this.sliderBoxWidth - 10;
        curX = tempX;
        if (curX < (minLeft + 6)) {
            curX = minLeft + 6;
            this.shiftSide = "left";
            this.shiftSpeed = Math.min(Math.round((minLeft - tempX) / 40), 10);
        } else if (curX > maxRight) {
            curX = maxRight;
            this.shiftSide = "right";
            this.shiftSpeed = Math.min(Math.round((tempX - maxRight) / 10), 10);
        } else {
            this.shiftSide = "";
            if (this.shiftSliderTimeout != 0) {
                clearInterval(this.shiftSliderTimeout);
                this.shiftSliderTimeout = 0;
                enableDragSelect(false);
            }
        }
        if (this.shiftSide != "") {
            if (this.shiftSliderTimeout == 0)
                this.shiftSliderTimeout = setInterval(ContextDelegate(this, this.shiftSlider), 5);
        }
        $get("AssetPage_time_stamp_change_slider").style.marginLeft = (curX - minLeft - 8) + "px";
    }
}

AssetPageTimestampSlider.prototype.shiftSlider = function() {
    var bgPosition = this.getShiftValue();
    var shiftUnit = this.shiftSpeed + 1;
    switch (this.shiftSide) {
        case "left":
            if ((bgPosition + shiftUnit) <= 0)
                $get("AssetPage_time_stamp_change_slider_timeline").style.backgroundPosition = (bgPosition + shiftUnit) + "px 0px";
            break;
        case "right":
            if ((bgPosition - shiftUnit) >= (this.sliderBoxWidth - this.stripWidth))
                $get("AssetPage_time_stamp_change_slider_timeline").style.backgroundPosition = (bgPosition - shiftUnit) + "px 0px";
    }
}

AssetPageTimestampSlider.prototype.timeStampStopDrag = function() {
  if (this.timestampDragging) {
    enableDragSelect(false);
    var bgPosition, sliderPosition, curShift;
    var shiftYear, shiftMonth, curDate;
    $get("AssetPage_time_stamp_change_slider").style.backgroundImage = "url('/Images/AssetPage/timestamp_slider.png')"
    this.timestampDragging = false;
    if (this.shiftSliderTimeout != 0) {
        clearInterval(this.shiftSliderTimeout);
        this.shiftSliderTimeout = 0;
        enableDragSelect(false);
    }
    // Calculating the result year:
    bgPosition = this.getShiftValue();
    sliderPosition = parseInt($get("AssetPage_time_stamp_change_slider").style.marginLeft) + 8;
    curShift = 0 - bgPosition + sliderPosition - 17;
    curShift = (curShift / 5 + 1500);
    shiftYear = Math.floor(curShift);
    shiftMonth = Math.floor((curShift - shiftYear) * 12);
    curDate = new Date();
    curDate.setTime(this.container.assetDate.date.valueOf());
    curDate.setFullYear(shiftYear);
    curDate.setMonth(shiftMonth);
    this.container.controls.time_stamp.specialFunction("update", { from: "slider", date: curDate });
  }
}

AssetPageTimestampSlider.prototype.getShiftValue = function() {
    var bgPositionString = $get("AssetPage_time_stamp_change_slider_timeline").style.backgroundPosition;
    var curSplit;
    if (bgPositionString == "") {
        return 0;
    } else {
        curSplit = bgPositionString.split("px");
        return parseInt(curSplit[0]);
    }
}

// Timestamp drag [end]


// helpers

// ********* Comments object [start]

function AssetPageComments(container) {
    this.container = container;
    this.comments = new Array();
    this.commentIDs = new Object();
    this.AddCommentState = false;
}

AssetPageComments.prototype.addComment = function(commentObject) {
    this.commentIDs[commentObject.CommentID] = this.comments.length;
    this.comments.push(new AssetPageComment(commentObject));
}

AssetPageComments.prototype.getHtml = function() {
    var curHtml = "";
    for (var i = 0; i < this.comments.length; i++) {
        curHtml += this.comments[i].html;
    }
    return curHtml;
}

AssetPageComments.prototype.postComment = function() {
    if (this.AddCommentState) return;
    if ($get("AssetPage_comment_textarea").value == "")
    {
        EnablePostCommentBtn();
        return;
    }
    this.AddCommentState = true;
    this.container.message.setTemplateMessage("processing");
    //enableButton("AssetPage_AddYourComment_post_button", false);
    var commentText = $get("AssetPage_comment_textarea").value;

    pendingAction.functionName = "Comments.AddComment";
    pendingAction.functionParams = new Array(
    { name: "EntityID", value: this.container.assetData.ID },
    { name: "Owner", value: this.container.assetData.OwnerID },
    { name: "SerType", value: 2 },
    { name: "Contents", value: escape(commentText) });
    pendingAction.callbackData = { onSuccessFunction: assetPageCB.postComments, onFailureFunction: assetPageCB.generalFail, action: "post_comment" };
    executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
}

AssetPageComments.prototype.commentAction = function(commentID, actionName) {
    this.comments[this.commentIDs[commentID]].commentAction(actionName);
}

// ********* Comments object [end]


// ********* Single Comment [start]

function AssetPageComment(commentObject) {
  this.id = commentObject.CommentID;
  this.createorIcon = commentObject.CreatorIconUrl;
  this.creatorName = commentObject.CreatorName;
  if (commentObject.CreatorID == assetPage.viewerID)
    this.creatorUrl = "";
  else
    this.creatorUrl = "http://" + window.location.host + commentObject.CreatorAoMURL;
  this.text = commentObject.Contents;
  this.canModify = commentObject.CanModify;
  this.Created = new AssetPageDate(commentObject.Created, datePrecisions.SECOND, "string");
  this.html = this.generateCommentHtml();
  this.state = 0;
}

AssetPageComment.prototype.generateCommentHtml = function() {
  var nowDate = new Date();
  var dateDif = nowDate - this.Created.date;
  if (dateDif < 0) dateDif = 0;
  var dif = {
    days: Math.floor(dateDif / 1000 / 3600 / 24),
    hours: Math.floor(dateDif / 1000 / 3600),
    minutes: Math.floor(dateDif / 1000 / 60)
  }
  var commentDate;
  var commentDateString;
  var timeUnit;
  var dateFormat = (nowDate.getFullYear() == this.Created.date.getFullYear()) ? assetPageConsts.DATE_2 : assetPageConsts.DATE_3;
  if (dif.minutes < 60) {
    // less than hour
    timeUnit = "minute";
    if (dif.minutes != 1) timeUnit += "s";
    commentDateString = this.Created.getFormattedDate(assetPageConsts.TIME_1);
    commentDateString += " (" + dif.minutes + " " + timeUnit + " ago)";
  } else if (dif.hours <= 24) {
    timeUnit = "hour";
    if (dif.hours != 1) timeUnit += "s";
    commentDateString = this.Created.getFormattedDate(dateFormat);
    commentDateString += " (" + dif.hours + " " + timeUnit + " ago)";
  } else if (dif.days <= 30) {
    timeUnit = "day";
    if (dif.hours != 1) timeUnit += "s";
    commentDateString = this.Created.getFormattedDate(dateFormat);
    commentDateString += " (" + dif.days + " " + timeUnit + " ago)";
  } else {
    commentDateString = this.Created.getFormattedDate(dateFormat);
  }
  var curHtml = "";
  curHtml += "<div class=\"AssetPage_comment\" id=\"AssetPage_comment_" + this.id + "\">";
  curHtml += "<div class=\"AssetPage_comment_icon\" ";
  curHtml += "style=\"background-image: url('" + this.createorIcon + "')\"></div>";
  curHtml += "<div class=\"AssetPage_comment_body\">";
  if (this.creatorUrl == "") {
    curHtml += "<strong>" + this.creatorName + "</strong>";
  } else {
    curHtml += "<span class=\"AssetPage_comment_username\" ";
    curHtml += "onclick=\"window.open('" + this.creatorUrl + "')\"";
    curHtml += ">" + this.creatorName + "</span>";
  }
  curHtml += "&nbsp;says:<br />";
  curHtml += "<span id=\"AssetPage_comment_text_" + this.id + "\">" + this.text + "</span>";
  curHtml += "<span id=\"AssetPage_comment_editor_placeholder_" + this.id + "\"></span>";
  curHtml += "<br />";
  curHtml += "<div class=\"AssetPage_comment_date\">";
  curHtml += commentDateString;
  curHtml += "</div>";
  if (this.canModify) {
    curHtml += "<div class=\"AssetPage_comment_action\" ";
    curHtml += "id=\"AssetPage_comment_edit_link_" + this.id + "\" ";
    curHtml += "onclick=\"assetPage.comments.commentAction(" + this.id + ", 'open_editor')\">edit</div>";
    curHtml += "<div class=\"AssetPage_comment_action\" ";
    curHtml += "id=\"AssetPage_comment_delete_link_" + this.id + "\" ";
    curHtml += "onclick=\"assetPage.comments.commentAction(" + this.id + ", 'delete')\">delete</div>";
  }
  curHtml += "</div>";
  curHtml += "</div>";
  return curHtml;
}

AssetPageComment.prototype.commentAction = function(actionName) {
  switch (actionName) {
    case 'open_editor':
      var curHtml = "";
      curHtml += "<textarea id=\"AssetPage_comment_edit_" + this.id + "\" ";
      curHtml += "class=\"AssetPage_comment_editor\">" + this.text + " </textarea>";
      curHtml += "<div class=\"blueButton\" id=\"AssetPage_comment_edit_done_" + this.id + "\">";
      curHtml += "<span onclick=\"assetPage.comments.commentAction(" + this.id + ", 'done_editing')\">";
      curHtml += "<div class=\"buttonRight\"></div>";
      curHtml += "<div class=\"buttonBody\">Done</div>";
      curHtml += "<div class=\"buttonLeft\"></div>";
      curHtml += "</span>";
      curHtml += "<div class=\"AssetPage_comment_action\" ";
      curHtml += "onclick=\"assetPage.comments.commentAction(" + this.id + ", 'close_editor')\" ";
      curHtml += "style=\"float:right;margin-right:5px;\">cancel</div>";
      curHtml += "</div>";
      $get("AssetPage_comment_text_" + this.id).style.display = "none";
      $get("AssetPage_comment_edit_link_" + this.id).style.display = "none";
      $get("AssetPage_comment_delete_link_" + this.id).style.display = "none";
      $get("AssetPage_comment_editor_placeholder_" + this.id).innerHTML = curHtml;
      $get("AssetPage_comment_edit_" + this.id).focus();
      break;
    case 'close_editor':
      if (this.state == 1) return;
      $get("AssetPage_comment_text_" + this.id).style.display = "block";
      $get("AssetPage_comment_edit_link_" + this.id).style.display = "block";
      $get("AssetPage_comment_delete_link_" + this.id).style.display = "block";
      $get("AssetPage_comment_editor_placeholder_" + this.id).innerHTML = "";
      break;
    case 'done_editing':
      var curHtml = $get("AssetPage_comment_edit_" + this.id).value;
      enableButton("AssetPage_comment_edit_done_" + this.id, false);
      this.state = 1;
      assetPage.message.setTemplateMessage("processing");
      pendingAction.functionName = "Comments.EditComment";
      pendingAction.functionParams = new Array(
            { name: "CommentID", value: this.id },
            { name: "SerType", value: 2 },
            { name: "Contents", value: escape(curHtml) });
      pendingAction.callbackData = { onSuccessFunction: assetPageCB.editComments, onFailureFunction: assetPageCB.generalFail, action: "edit_comment", CommentID: this.id };
      executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
      this.commentAction('close_editor');
      break;
    case 'delete':
      if (this.state == 2) return;
      if (confirm("Are you sure you want to delete this comment?")) {
        this.state = 2;
        this.html = "";
        assetPage.message.setTemplateMessage("processing");
        pendingAction.functionName = "Comments.DeleteComment";
        pendingAction.functionParams = new Array(
                { name: "SerType", value: 2 },
                { name: "CommentID", value: this.id });
        pendingAction.callbackData = { onSuccessFunction: assetPageCB.deleteComment, onFailureFunction: assetPageCB.generalFail, action: "delete_comment", CommentID: this.id };
        executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
      }
      break;
    case 'edited':
      var curHtml = $get("AssetPage_comment_edit_" + this.id).value;
      enableButton("AssetPage_comment_edit_done_" + this.id, true);
      this.state = 0;
      $get("AssetPage_comment_text_" + this.id).innerHTML = curHtml;
      this.text = curHtml;
      this.commentAction('close_editor');
      break;
    case 'deleted':
      this.state = 0;
      $get("AssetPage_comments_container").innerHTML = assetPage.comments.getHtml();
      break;
  }
}

// ********* Single Comment [end]
  
// ********* Album [start]
/*
Height: 40
TimelineID: NaN
Width: 72
OwnerID: 0
BalloonService: null
ID: 614487
Date: 6/4/2008 12:55
Type: Asset
aomTypeId: 1
Title: hstrip.jpg
Url: http://storage4.allofme.com/0891e8c7/c484f870/1804e402/af1dcdfc_T.jpg
*/
function AssetPageAlbum(container) {
    this.container = container;
    this.assets = this.container.flashAsset.assetArray;
}

AssetPageAlbum.prototype.assetClicked = function(id) {
    // navigating to an asset in album
    // Synthesizing flashAsset object (as if it was clicked from the timeline):
    var synthesizedFlashAsset = {
        Type: "Asset",
        OwnerID: this.container.flashAsset.OwnerID,
        ID: id,
        TimelineID: this.container.assetData.TimelineID
    };
    this.container.navigateAsset(synthesizedFlashAsset, "AlbumNavigation");
    flash.assetPageSelectAssetInAlbum(id, this.container.parentAlbum.ID, this.container.assetData.TimelineID);
}

AssetPageAlbum.prototype.arrowClicked = function(id) {
    //alert("arrow clicked: " + id);
}


// ********* Album [end]

// ********* Stars [start]

function AssetPageStars(assetID, ownerID, ratingAvg, canRate, numRaters) {
  this.assetID = assetID;
  this.ownerID = ownerID;
  this.ratingAvg = ratingAvg;
  this.canRate = canRate;
  this.numRaters = numRaters;
  this.stars = new Array();
  var curRating = Math.round(this.ratingAvg * 2) / 2 - 1;
  //CanRate RatingAvg NumRaters ViewerRating
  for (var i = 0; i < 5; i++) {
    this.stars.push(new AssetPageStar(this, i));
  }
  this.init();
}

AssetPageStars.prototype.init = function() {
  var curStar;
  var curRating = Math.round(this.ratingAvg * 2) / 2 - 1;
  for (var i = 0; i < 5; i++) {
    curStar = this.stars[i];
    if (curRating > -1) {
      if (i <= curRating)
        curStar.hilite(true);
      else if ((i - 0.5) == curRating)
        curStar.halfHilite();
      else
        curStar.hilite(false);
    } else
      curStar.hilite(false);
    curStar.enable(this.canRate);
  }
}

AssetPageStars.prototype.mouseCommand = function(command, starID) {
  var curSplit = starID.split("_");
  var curIndex = parseInt(curSplit[2])
  var curStar = this.stars[curIndex];
  var i;
  switch (command) {
    case "over":
      for (i = 0; i <= 4; i++) {
        if (i <= curIndex) {
          this.stars[i].htmlObject.style.backgroundImage = "url(/Images/AssetPage/star_marked.png)";
        } else {
          this.stars[i].htmlObject.style.backgroundImage = "url(/Images/AssetPage/star_empty.png)";
        }
      }
      break;
    case "out":
      for (i = 0; i <= 4; i++)
        this.stars[i].tempHilite(false);
      break;
    case "click":
      for (i = 0; i < 5; i++)
        this.stars[i].enable(false);
      assetPage.message.setTemplateMessage("processing");
      pendingAction.functionName = "Ratings.AddRating";
      pendingAction.functionParams = new Array(
      { name: "EntityID", value: this.assetID },
      { name: "Owner", value: this.ownerID },
      { name: "Rating", value: "" + (curIndex + 1) },
      { name: "SerType", value: "2" });
      pendingAction.callbackData = { onSuccessFunction: assetPageCB.rating, onFailureFunction: assetPageCB.generalFail, action: "set_title" };
      executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
      break;
  }
}

AssetPageStars.prototype.ratingComplete = function(newRating) {
  this.ratingAvg = newRating;
  this.init();
}

AssetPageStars.prototype.idleView = function() {
  for (var i = 0; i < this.stars.length; i++) {
    this.stars[i].idleView();
  }
}

function AssetPageStar(controller, index) {
  this.controller = controller;
  this.index = index;
  this.htmlObject = $get("AssetPage_star_" + index);
  this.hiliteConsts = { DIMMED: 0, HALF: 1, FULL: 2 }
  this.hilited = this.hiliteConsts.DIMMED;
}

AssetPageStar.prototype.hilite = function(hilite) {
  this.hilited = hilite ? this.hiliteConsts.FULL : this.hiliteConsts.DIMMED; // 
  this.tempHilite(hilite);
}

AssetPageStar.prototype.halfHilite = function() {
  this.hilited = this.hiliteConsts.HALF;
  this.htmlObject.style.backgroundImage = "url(/Images/AssetPage/star_half.png)";
}

AssetPageStar.prototype.tempHilite = function(tempHilite) {
  var suffix;
  if (tempHilite) {
    suffix = "marked.png";
  } else {
    switch (this.hilited) {
      case this.hiliteConsts.DIMMED: suffix = "empty.png"; break;
      case this.hiliteConsts.HALF: suffix = "half.png"; break;
      case this.hiliteConsts.FULL: suffix = "marked.png"; break;
    }
  }
  this.htmlObject.style.backgroundImage = "url(/Images/AssetPage/star_" + suffix + ")";
}

AssetPageStar.prototype.enable = function(enable) {
  this.enabled = enable;
  if (this.enabled) {
    this.htmlObject.onmouseover = function() { assetPage.starsController.mouseCommand("over", this.id) };
    this.htmlObject.onmouseout = function() { assetPage.starsController.mouseCommand("out", this.id) };
    this.htmlObject.onclick = function() { assetPage.starsController.mouseCommand("click", this.id) };
    this.htmlObject.style.cursor = "pointer";
    switch (this.index) {
      case 0: this.htmlObject.setAttribute("title", "Poor"); break;
      case 1: this.htmlObject.setAttribute("title", "Nothing special"); break;
      case 2: this.htmlObject.setAttribute("title", "Just OK"); break;
      case 3: this.htmlObject.setAttribute("title", "Pretty cool"); break;
      case 4: this.htmlObject.setAttribute("title", "Awesome!"); break;
    }
  } else {
    this.htmlObject.onmouseover = function() { return false };
    this.htmlObject.onmouseout = function() { return false };
    this.htmlObject.onclick = function() { return false };
    this.htmlObject.style.cursor = "default";
    if (this.controller.numRaters)
      this.htmlObject.setAttribute("title", this.controller.numRaters + " Ratings");
    else
      this.htmlObject.setAttribute("title", "Login to rate");
  }
}

AssetPageStar.prototype.idleView = function() {
  this.htmlObject.style.backgroundImage = "url(/Images/AssetPage/star_empty.png)";
  this.htmlObject.setAttribute("title", "");
}

// ********* Stars [end]

// ********* Date [start]

function AssetPageDate(curDate, curPrecision, curType) {
  this.date = new Date();
  this.monthNames = AssetPageGetLongMonths();
  this.shortMonthNames = AssetPageGetShortMonths();
  this.precision = curPrecision;
  switch (curType) {
    case "string":
      var split1 = curDate.split("/");
      var split2 = curDate.split(" ");
      var split3 = split2[1].split(":");
      // Getting month numb
      var monthNum = 0;
      switch (split1[0].length) {
        case 1: case 2:
          // Month name represented by number with leading zeros
          monthNum = parseInt(split1[0]) - 1;
          break;
        default:
          // Month name represented by a short string
          var monthInitials = split1[0].toLowerCase();
          monthInitials = monthInitials.substr(0, 3);
          for (var i = 0; i < 12; i++) {
            if (this.shortMonthNames[i].toLowerCase() == monthInitials) {
              monthNum = i;
              break;
            }
          }
      }
      this.date.setMonth(monthNum);
      this.date.setDate(split1[1]);
      this.date.setFullYear(split1[2].substr(0, 4));
      this.date.setHours(split3[0]);
      this.date.setMinutes(split3[1]);
      this.date.setSeconds(0);
      this.date.setMilliseconds(0);
      break;
    default:
      this.date.setTime(curDate.getTime());
  }
}

AssetPageDate.prototype.getFormattedDate = function(curFormat) {
  var sFormatted = "";
  var curMonth = this.date.getMonth() + 1;
  switch (curFormat) {
    case assetPageConsts.DATE_1: //July 2, 2007
      if (this.precision <= datePrecisions.DAY) {
        sFormatted += this.getMonthName() + " ";
        sFormatted += this.date.getDate() + ", ";
      } else if (this.precision == datePrecisions.MONTH) {
        sFormatted += this.getMonthName() + ", ";
      }
      sFormatted += this.date.getFullYear();
      break;
    case assetPageConsts.DATE_2: //July 2
      // used for comments, ignoring precision
      sFormatted += this.getMonthName() + " ";
      sFormatted += this.date.getDate();
      break;
    case assetPageConsts.DATE_3: //07/02/2007
      // used for comments, ignoring precision
      sFormatted += this.setLeadingZero(this.date.getMonth() + 1) + "/";
      sFormatted += this.setLeadingZero(this.date.getDate()) + "/";
      sFormatted += this.date.getFullYear();
      break;
    case assetPageConsts.TIME_1: //13:25
      // used for comments, ignoring precision
      sFormatted += this.setLeadingZero(this.date.getHours());
      sFormatted += ":";
      sFormatted += this.setLeadingZero(this.date.getMinutes());
      break;
    case assetPageConsts.TIME_2: //1:25pm
      // used internally, ignoring precision
      var curHour = this.date.getHours()
      var ampm = (curHour >= 12) ? "pm" : "am";
      if (curHour > 12) curHour = curHour - 12;
      if (curHour == 0) curHour = 12;
      sFormatted += curHour + ":";
      sFormatted += this.setLeadingZero(this.date.getMinutes()) + ampm;
      break;
    case assetPageConsts.TIME_3: //1pm
      // used internally, ignoring precision
      sFormatted += this.date.getHours() + ((curHour >= 12) ? "pm" : "am");
      break;
    case assetPageConsts.DATE_TIME_1: //July 2, 2007, 1:25pm
      sFormatted = this.getFormattedDate(assetPageConsts.DATE_1);
      if (this.precision == datePrecisions.HOUR) {
        sFormatted += ", " + this.getFormattedDate(assetPageConsts.TIME_3);
      } else if (this.precision <= datePrecisions.HOUR){
        sFormatted += ", " + this.getFormattedDate(assetPageConsts.TIME_2);
      }
      break;
    case assetPageConsts.DATE_TIME_2: //06/04/2008 15:33
      sFormatted = this.getFormattedDate(assetPageConsts.DATE_3);
      if (this.precision == datePrecisions.HOUR) {
        sFormatted += ", " + this.date.getHours() + ":00";
      } else if (this.precision <= datePrecisions.HOUR) {
        sFormatted += ", " + this.getFormattedDate(assetPageConsts.TIME_1);
      }
      break;
    case assetPageConsts.FLASH_DATE: // May/13/2006 22:26
      // used for sending dates to Flash. ignoring precision
      sFormatted = this.getMonthName(true) + "/";
      sFormatted += this.setLeadingZero(this.date.getDate()) + "/";
      sFormatted += this.date.getFullYear() + " ";
      sFormatted += this.getFormattedDate(assetPageConsts.TIME_1);
      break;
  }
  return sFormatted;
}

AssetPageDate.prototype.setLeadingZero = function(curNumber) {
    return (curNumber < 10) ? "0" + curNumber : curNumber;
}

AssetPageDate.prototype.getMonthName = function(isShort) {
    return isShort ? this.shortMonthNames[this.date.getMonth()] : this.monthNames[this.date.getMonth()];
}

AssetPageDate.prototype.update = function(newDate) {
    this.date.setTime(newDate.valueOf());
    this.updateFields();
}

AssetPageDate.prototype.updateFields = function() {
    $get("AssetPage_asset_date_text").innerHTML = this.getFormattedDate(assetPageConsts.DATE_1);
    $get("AssetPage_time_stamp_control_closed").innerHTML = this.getFormattedDate(assetPageConsts.DATE_TIME_1);
    $get("AssetPage_time_stamp_current").innerHTML = this.getFormattedDate(assetPageConsts.DATE_TIME_1);
}

function AssetPageGetShortMonths() {
  return [
  "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
}

function AssetPageGetLongMonths() {
  return ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"];
}

// ********* Date [end]

// ********* Api Queue [start] (calling more than one api function) 

function AssetPageApiQueue() {
}

AssetPageApiQueue.prototype.init = function(endFunction) {
    this.queue = new Array();
    this.index = -1;
    this.endFunction = endFunction;
}

AssetPageApiQueue.prototype.addToQueue = function(apiFunction, params) {
    this.queue.push({ functionName: apiFunction, params: params });
}

AssetPageApiQueue.prototype.start = function() {
    this.index = 0;
    assetPage.message.setTemplateMessage("processing");
    this.triggerCurrent();
}

AssetPageApiQueue.prototype.triggerCurrent = function() {
    pendingAction.pending = true;
    pendingAction.numOfRetries = 0;
    pendingAction.functionName = this.queue[this.index].functionName;
    pendingAction.functionParams = this.queue[this.index].params;
    pendingAction.callbackData = {
        onSuccessFunction: ContextDelegate(this, this.callbackSuccess),
        onFailureFunction: ContextDelegate(this, this.callbackFail)
    };
    executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
}

AssetPageApiQueue.prototype.callbackSuccess = function() {
  if (this.queue[this.index].functionName.indexOf("Sharing.") == 0) {
    var i, j;
    var targetList = new Array();
    for (i = 0; i < this.queue[this.index].params.length; i++) {
      if (this.queue[this.index].params[i].name == "TargetIDs") {
        targetList = this.queue[this.index].params[i].value;
        targetList = targetList.split(",");
        break;
      }
    }
    for (i = 0; i < targetList.length; i++) {
      switch (this.queue[this.index].functionName) {
        case "Sharing.UnshareEntities":
          for (j = 0; j < assetPage.assetData.share.length; j++) {
            if (assetPage.assetData.share[j].ID == targetList[i]) {
              assetPage.assetData.share.splice(j, 1);
              break;
            }
          }
          break;
        case "Sharing.SimplyShareEntities":
          assetPage.assetData.share.push({ "ID": targetList[i], "Verb": 7 });
          break; 
      }
    }
    $get("AssetPage_share_control_closed").innerHTML = assetPage.getShareWithNames();
  }
  if (++this.index == this.queue.length)
    this.endQueue();
  else
    this.triggerCurrent();
}

AssetPageApiQueue.prototype.callbackFail = function() {
  assetPage.message.setMessage("Oops... could not complete task", false, true, true);
  this.endQueue();
}

AssetPageApiQueue.prototype.endQueue = function() {
  assetPage.message.setTemplateMessage("done");
  if (typeof (this.endFunction) != "undefined")
    setTimeout(this.endFunction, 200);
}

// ********* Api Queue [end]

// ********* Message [start]

function AssetPageMessage() {
  this.htmlObject = $get("AssetPage_message");
  this.processingInterval = 0;
  this.hideTimeout = 0;
  this.hide();
}

AssetPageMessage.prototype.setMessage = function(message, processing, autoHide, asAlert) {
  this.clearProcessingInterval();
  this.clearHideTimeout();
  this.message = message;
  this.htmlObject.innerHTML = message;
  this.htmlObject.style.paddingLeft = asAlert ? "18px" : "4px";
  this.htmlObject.style.backgroundImage = asAlert ? "url(/Images/AssetPage/AlertNote.gif)" : "";
  this.htmlObject.style.color = asAlert ? "#dd0000" : "#000000";
  this.htmlObject.style.visibility = "visible";
  if (processing) {
    this.processingDot = 0;
    this.processingInterval = setInterval(ContextDelegate(this, this.processing), 500);
  }
  if (autoHide) {
    this.hideTimeout = setTimeout(ContextDelegate(this, this.hide), asAlert ? 4000 : 2000);
  }
}

AssetPageMessage.prototype.setTemplateMessage = function(template){
  switch(template){
    case "processing":
      this.setMessage("Processing, please wait", true, false);
      break;
    case "done":
      this.setMessage("Done", false, true);
      break;
  }
}

AssetPageMessage.prototype.stopProcessing = function(hide) {
  this.clearProcessingInterval();
  if (hide) this.hide();
}

AssetPageMessage.prototype.processing = function() {
  var dots = "";
  for (var i = 0; i < this.processingDot; i++) {
    dots += ".";
  }
  this.htmlObject.innerHTML = this.message + dots;
  if (this.processingDot++ == 4) this.processingDot = 0;
}

AssetPageMessage.prototype.clearProcessingInterval = function() {
  if (this.processingInterval) {
    clearInterval(this.processingInterval);
    this.processingInterval = 0;
  }
}

AssetPageMessage.prototype.clearHideTimeout = function() {
  if (this.hideTimeout) {
    clearInterval(this.hideTimeout);
    this.hideTimeout = 0;
  }
}

AssetPageMessage.prototype.hide = function() {
  this.htmlObject.style.visibility = "hidden";
  this.clearHideTimeout();
}

AssetPageMessage.prototype.idleView = function() {
  this.clearProcessingInterval();
  this.hide();
}


// ********* Message [end]

// ********* Navigation Dropdown [start]

function assetPageShowNavigationDropdown(ddList) {
  var dropDownMenu = $get("AssetPage_navigation_dropdown");
  if (dropDownMenu.style.display == "block") {
    assetPageHideNavigationDropdown();
    return;
  }

  var html = "";
  for (var i = 0; i < ddList.length; i++) {
      html += '<div class="';
      html += (ddList[i].selected) ? "element selected" : "element";
      html += '" id="AssetPage_nav_dropdown_element_' + ddList[i].value;
      html += '" onclick="assetNavigationClicked(' + ddList[i].value + ')">' + ddList[i].label + '</div>';
  }
  dropDownMenu.innerHTML = html;
  dropDownMenu.style.display = "block";
  var h = dropDownMenu.offsetHeight;
  var t = myHeight - h - assetPageConsts.BOTTOM_SHORT;
  dropDownMenu.style.top = t + "px";
  // preventing immidieate mouseup:
  assetPageDropdownTimeout = true;
  markerController.hideCanvas();
  setTimeout(assetPageEnableCloseNavDropdown, 500);
}

function assetPageHideNavigationDropdown() {
  $get("AssetPage_navigation_dropdown").style.display = "none";
  markerController.showCanvas();
}

function assetNavigationClicked(indx) {
  assetPageHideNavigationDropdown()
  flash.navigationDropdownSelected(indx);
}

function assetPageEnableCloseNavDropdown() {
  assetPageDropdownTimeout = false;
}

// ********* String formatting [start]

function comaDelimitNumber(numString) {
    if (numString.length < 4) return numString;
    var fString1, fString2;
    fString1 = fString2 = "";
    var j = 0;
    for (var i = (numString.length - 1); i >= 0; i--) {
        fString1 += numString.charAt(i);
        if (j++ == 2) {
            j = 0;
            fString1 += ",";
        }
    }
    if (fString1.charAt(0) == ",") fString1 = fString1.substr(1, fString1.length);
    for (i = (fString1.length - 1); i >= 0; i--) {
        fString2 += fString1.charAt(i);
    }
    return fString2;
}

// ********* String formatting [end]

// ********* Disable selection [start]

function disableSelection(target) {
    if (typeof target.onselectstart != "undefined") //IE route
        target.onselectstart = function() { return false }
    else if (typeof target.style.MozUserSelect != "undefined") //Firefox route
        target.style.MozUserSelect = "none";
    else //All other route (ie: Opera)
        target.onmousedown = function() { return false }
}

// ********* Disable selection [end]

// ********* Options factory [start]

function createRangeOptions(start, end, selected, leadingZeros, addNullSelection) {
    var i;
    var curOptions = "";
    if (addNullSelection) {
      curOptions += '<option value="--"';
      if (selected == "--") curOptions += " selected";
      curOptions += ">--</option>";
    }    
    for (i = start; i <= end; i++) {
        curOptions += "<option value='" + i + "'";
        if (i == selected) curOptions += " selected";
        curOptions += ">";
        curOptions += leadingZeros ? padDigits(i, 2) : i;
        curOptions += "</option>";
    }
    return curOptions;
}

function createListOptions(curList, selected, addNullSelection) {
  var i;
  var curOptions = "";
  if (addNullSelection) {
    curOptions += '<option value="--"';
    if (selected == "--") curOptions += " selected";
    curOptions += ">--</option>";
  }    
  for (i = 0; i < curList.length; i++) {
    curOptions += "<option value='" + i + "'";
    if (i == selected) curOptions += " selected";
    curOptions += ">" + curList[i] + "</option>";
  }
  return curOptions;
}

function createPropListOptions(curList, selected) {
  var i;
  var curOptions = "";
  for (i = 0; i < curList.length; i++) {
    curOptions += "<option value='" + curList[i].id + "'";
    if (curList[i].id == selected) curOptions += " selected";
    curOptions += ">" + curList[i].value + "</option>";
  }
  return curOptions;
}

function createDateSelectTag(controlType, curOption) {
    return '\
    <select\
      id="AssetPage_time_stamp_change_' + controlType + '"\
      onchange="assetPage.controls.time_stamp.specialFunction(\'update\', {from: \'selection\', control: \'' + controlType + '\'})">\
  ' + curOption + '</select>';
}

function padDigits(n, totalDigits) {
    n = n.toString();
    var pd = '';
    if (totalDigits > n.length)
        for (i = 0; i < (totalDigits - n.length); i++)
        pd += '0';
    return pd + n.toString();
}

// ********* Options factory [end]

// ********* Tag List factory [start]

function getTagListLine(tagObject) {
    var tagsHtml = '\
    <div style="clear:left" id="AssetPage_tag_list_item_' + tagObject.ID + '">\
      <div class="list_item">' + tagObject.Title + '</div>';
    if (tagObject.CanDelete) {
        tagsHtml += '\
            <div class="list_item_delete" onclick="assetPage.controls.tag.specialFunction(\'delete_tag\', \'' + tagObject.ID + '\')">[x]</div>';
    }
    tagsHtml += '\
    </div>';
    return tagsHtml;
}

// ********* Tag List factory [end]

// ********* Date helpers [start]

function getDaysInMonth(curDate) {
  var i, numDays;
  var daysOptions = "";
  switch (curDate.getMonth()) {
    case 0: case 2: case 4: case 6: case 7: case 9: case 11:
      numDays = 31;
      break;
    case 1:
      var curYear = curDate.getFullYear();
      var leapYear = false;
      if (curYear % 4 == 0)
        if (curYear % 100 != 0)
          leapYear = true;
        else
          if (curYear % 400 == 0)
            leapYear = true;
          else
            leapYear = false;
      if (leapYear)
        numDays = 29;
      else
        numDays = 28;
      break;
    default:
      numDays = 30;
  }
  return numDays;
}

function getDayInYear(curDate) {
    var i;
    var days = 0;
    for (i = 0; i < curDate.getMonth(); i++) {
        days += getDaysInMonth(curDate);
    }
    days += curDate.getDate();
    return days;
}

function getElementAbsoluteX(oElementName) {
    var oElement = $get(oElementName);
    var iReturnValue = 0;
    while (oElement != null) {
        iReturnValue += oElement.offsetLeft;
        oElement = oElement.offsetParent;
    }
    return iReturnValue;
}

function assetPageYearInputFilter(e) {
  var keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
  switch (keyCode) {
      case 8: case 9: case 27: case 37: case 39:
      case 46: case 48: case 49: case 50: case 51:
      case 52: case 53: case 54: case 55: case 56:
      case 57: case 61:
          return true;
      case 13:
          assetPage.controls.time_stamp.specialFunction("update", { from: "selection", control: "year" });
          return false;
      default:
          return false;
  }
}

function assetPageYearInputFilterUp(inp) {
  if (inp.value.length == 5) {
    if (inp.value.charAt(0) != "-")
      inp.value = inp.value.substr(0, 4);
  }
  if (inp.valueOf.length == 6)
    inp.value = inp.value.substr(0, 5);
}

// ********* Date helpers [end]

// ********* Misc [start]

function AssetPageRemoveChildren(cell) {
  if (cell.hasChildNodes()) {
    while (cell.childNodes.length >= 1) {
      cell.removeChild(cell.firstChild);
    }
  }
}

function AssetPageScroll() {
  markerController.pageScroll();
}

function parseObject(obj, toPrompt) {
    var r = "";
    for (prop in obj) {
        r += prop + ": " + obj[prop]
        if (!toPrompt) r += "\n";
    }
    if (toPrompt)
        prompt("object", r);
    else
        alert(r);
}

function AssetPageClone(obj){
  if(obj == null || typeof(obj) != 'object')
    return obj;
  if(obj.constructor == Array)
    return [].concat(obj);
  var temp = {};
  for(var key in obj)
    temp[key] = AssetPageClone(obj[key]);
  return temp;
}

function buildContactLink(creatorAoMURL, contactName) {
  var link = '<a href="http://' + window.location.host + creatorAoMURL + '"';
  link += ' target="_blank">' + contactName + '</a>';
  return link;
}

function enableButton(buttonContainer, enabled) {
    var curContainer = $get(buttonContainer);
    var imgSuffix = enabled ? ".png" : "_dis.png";
    // switching background image
    for (var i = 0; i < curContainer.childNodes.length; i++) {
        curNode = curContainer.childNodes[i];
        switch (curNode.className) {
            case "buttonLeft":
                curNode.style.backgroundImage = "url(/Images/buttons/but_left" + imgSuffix + ")";
                break;
            case "buttonBody":
                curNode.style.backgroundImage = "url(/Images/buttons/but_bg" + imgSuffix + ")";
                break;
            case "buttonRight":
                curNode.style.backgroundImage = "url(/Images/buttons/but_right" + imgSuffix + ")";
                break;
        }
    }
    // switching cursor and color
    curContainer.style.cursor = enabled ? "pointer" : "default";
    curContainer.style.color = enabled ? "Black" : "#666666";
}

function AssetPageCompleteShareChanges() {
    //enableButton("AssetPage_share_ok", true);
    EnableShareBtn();
  assetPage.controls.share.close();
}

function AssetPageParseChosenTags() {
  var textboxValue = $get('AssetPage_tbTagName').value;
  var tagList = [], tag = "", currentChar;
  var multipleWordTag = false;
  // stripping out multiple white spaces:
  textboxValue += ' ';
  textboxValue = textboxValue.replace(/\s+/g, ' ');
  if (textboxValue == " ") {
      // no tags types:
      return [];
  }

  for (var i = 0, j = textboxValue.length; i < j; i++) {
      currentChar = textboxValue.charAt(i);
      switch (currentChar) {
          case ' ':
              if (multipleWordTag)
                  tag += ' ';
              else {
                  if (tag != "") {
                      tagList[tagList.length] = escape(tag);
                      tag = "";
                  }
              }
              break;
          case '"':
              if (multipleWordTag) {
                  if (tag != "") {
                    tagList[tagList.length] = escape(tag);
                      tag = "";
                  }
                  multipleWordTag = false;
              } else {
                  if (tag != "") {
                      // for the case of : ....baketball"new baseball"....
                    tagList[tagList.length] = escape(tag);
                      tag = "";
                  }
                  multipleWordTag = true;
              }
              break;
          default:
              tag += currentChar;
      }
  }
  return tagList;
}

function formatUrlTitle(curString) {
  if (curString == undefined) return "";
  curString = curString.replace(/\s+/g, '_');
  curString = curString.replace(/\/+/g, '_');
  curString = curString.replace(/\\+/g, '_');
  return curString;
}

function bodToAge(userID, refDate) {
  if (ContactCloud[userID] == undefined) return 120;
  var birthDate = birthDateToDate(ContactCloud[userID].BirthDate);
  difYears = refDate.getFullYear() - birthDate.getFullYear();
  if (refDate.getMonth() == birthDate.getMonth()) {
    if (refDate.getDate() < birthDate.getDate()) {
      difYears -= 1;
    }
  } else if (refDate.getMonth() < birthDate.getMonth()) {
    difYears -= 1;
  }
  return(difYears);
}

function birthDateToDate(birthDateString) {
  var birthDate = new Date();
  var split = birthDateString.split("/"); //Nov/23/1967
  var shortMonths = AssetPageGetShortMonths();
  birthDate.setFullYear(split[2]);
  for (var i in shortMonths) {
    if (shortMonths[i] == split[0]) {
      birthDate.setMonth(i, split[1]);
      break;
    }
  }
  return birthDate;
}

// ********* Misc [end]
