/***	cash to flash convertors	***/

/// helper methods convertinf IDs to object
function getAssetsByIds(ids)
{
    var idsArray = ids.split(",");
    var returnArray = new Array();
    
    for(var i = 0 ; i < idsArray.length ; i++)
    {
        returnArray.push(assets[idsArray[i]]);    
    }
    return returnArray;
}

function getAssetById(id) {
    return assets[id];
}

function getAlbumById(id) 
{
    var album = new Object();
    var containersArray = cacheBranches[0].Children;
    
    for (var i = 0 ; i < containersArray.length ; i++) {
    
        if (containersArray[i].ID == id) {
        
            //var containerObj = containersArray[i].Branch.Children[0];
            var containerObj = containersArray[i];
            album.ID = containerObj.ID
	        album.Title = containerObj.Title;
	        album.NumOfChildren = containerObj.NumOfChildren;
	        album.BranchType = containerObj.BranchType;
	        album.Date = containerObj.AlbumWhen;
	        
	        album.Children = new Array();
	        
            // add 10 assets as childers of the album
	        var nCount = containerObj.Children.length;
	        if (nCount > 0) {
	            var nCount = (nCount > 10 ? 10 : nCount);
	            for (var n = 0 ; n < nCount ; n++) {
                    var assetId = containerObj.Children[n].AssetObject.ID;
	                album.Children[n] = getAssetById(assetId);
	            }
	        }
            break;
        }
    }
    return album;
}


function goToAlbum(objId) {
    var album = getAlbumById(objId);
    flash.jumpToAlbum(album);
}

// gets an XML string and returns an XML DOM object
function getXMLDoc(XMLString)
{
	var xmlDoc;
	
	try //Internet Explorer
	{
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(XMLString);
        return xmlDoc;		
	}
	catch(e)
	{
		try //Firefox, Mozilla, Opera, etc.
		{
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(XMLString,"text/xml");
            return xmlDoc;		
		}
		catch(e)
		{			
			return null;
		}
	}
	return null;
}

// gets an XML file path string and returns an XML DOM object
function loadXMLDoc(XMLString) 
{
    try //Internet Explorer
    {
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
    }
    catch(e)
    {
        try //Firefox, Mozilla, Opera, etc.
        {
            xmlDoc=document.implementation.createDocument("","",null);
        }
        catch(e) {alert(e.message)}
    }
    try 
    {
        xmlDoc.async=false;
        xmlDoc.load(XMLString);
        return(xmlDoc);
    }
    catch(e) {alert(e.message)}
    return(null);
}


/***		data parsers		***/

// AomTypes handlers
function parseAoMTypesOnSuccess(recievedData, callbackData)
{
	var typeID, sidebarIconURL, iconURL, description, useThumb, assetPageTitle;
	
	for (var i = 0, j = recievedData.length; i < j; i++)
	{
		typeID = recievedData[i].AoMTypeID;
		sidebarIconURL = recievedData[i].SidebarIconURL;
		iconURL = recievedData[i].IconURL;
		description = recievedData[i].OpenText;	
		useThumb = recievedData[i].UseThumb;
		assetPageTitle = recievedData[i].AssetPageTitle;
		playerName = recievedData[i].PlayerName;
		
		AoMTypes[typeID.toString()] = {UseThumb:useThumb, SidebarIconURL:sidebarIconURL, IconURL:iconURL, AssetPageTitle:assetPageTitle, Description:description, PlayerName:playerName};
		AoMTypes.isLoaded = true;
	}
}

function parseAoMTypesOnFailure(callbackData)
{
	if (AoMTypes.numOfLoadingTries < Consts.ACTION_RETRIES)
	{
		AoMTypes.numOfLoadingTries++;
		executeWebRequest("AoMTypes.GetAoMTypes",[{name:"SerType", value:2}],{onSuccessFunction:parseAoMTypesOnSuccess, onFailureFunction:parseAoMTypesOnFailure});
	}
}

// News Feed handdler
function parseNewsFeedOnSuccess(recievedData, callbackData)
{

    // viewr ID is required to continue
    if (!viewer.ID) {
        NewsFeed.numOfLoadingTries++;    
	    if (NewsFeed.numOfLoadingTries < Consts.ACTION_RETRIES)
	    {
	        // no Viewr OBJECT so wait
            var date = new Date();
            var curDate = null;
            do {curDate = new Date();}
            while(curDate-date < 500);
            // now retry
            parseNewsFeedOnSuccess(recievedData, callbackData);
	    }
        return;
    }

    var type, typeID, id, title, layer, owner, aomTypeID, url, when, height, width, byParent;
    var rowId, ids, aomType, idsArr, aomTypesString, iconURL;

    // going to the right elements of the XML
    var entityRows   = recievedData.documentElement.getElementsByTagName('Children')[0].getElementsByTagName('EntityLayer');
    var newsFeedRows = recievedData.documentElement.getElementsByTagName('NewsFeed')[0].getElementsByTagName('Rows')[0].getElementsByTagName('Row');

    var assetRowObj = []; // holds the EntityLayer rows where type="Asset"
    var albumRowObj = []; // holds the EntityLayer rows where type="Album"
    var newsFeedObj = []; 

    // puts the asset rows into an object with owner + assetId as the object Id
    for (var i = 0 ; i < entityRows.length ; i++) {

        type = entityRows[i].getAttribute('type')
        byParent = entityRows[i].getAttribute('ByParent')

        // get only first level children
        if (!(type == "Asset" && byParent == "true")) {
            typeID = entityRows[i].getAttribute('TypeID')
            id = entityRows[i].getAttribute('ID')
            title = entityRows[i].getAttribute('Title')
            layer = entityRows[i].getAttribute('Layer')
            owner = entityRows[i].getAttribute('Owner')
            aomTypeID = entityRows[i].getAttribute('AomTypeID')
            url = entityRows[i].getAttribute('Url')
            when = entityRows[i].getAttribute('When')
            height = entityRows[i].getAttribute('Height')
            width = entityRows[i].getAttribute('Width')

            // populate arrays to hold the news feed first level children
            if (type == "Album") {
                albumRowObj[owner.toString() + id.toString()] = {Type:type, TypeID:typeID, ID:id, Title:title, Layer:layer, Owner:owner, AomTypeID:aomTypeID, Url:url, When:when, Height:height, Width:width, ByParent:byParent}
            } else {
                assetRowObj[owner.toString() + id.toString()] = {Type:type, TypeID:typeID, ID:id, Title:title, Layer:layer, Owner:owner, AomTypeID:aomTypeID, Url:url, When:when, Height:height, Width:width, ByParent:byParent}
            }
        }
    }

    // go through the news rows
    for (var i = 0; i < newsFeedRows.length; i++) {

        type = newsFeedRows[i].getAttribute('type')
        when = newsFeedRows[i].getAttribute('When')
        ids = newsFeedRows[i].getAttribute('Ids')
        owner = newsFeedRows[i].getAttribute('Owner')
        aomType = newsFeedRows[i].getAttribute('AomType')
        rowId = '4' + i.toString() + owner
        //iconURL = AoMTypes[aomType].SidebarIconURL

        // init arrays
        idsArr = null;
        idsArr = ids.split(" ");

        childrensArr = null;
        childrensArr = [idsArr.length];

        // search the children in the correct array
        var ext = "";
        if (type == "AlbumRow") {

            if (idsArr.length > 1) ext = "s";
            
            if (viewer.ID.toString() == owner) {
                title = idsArr.length + " new album" + ext;
            } else {
                title = idsArr.length + " album" + ext + " from " + ContactCloud[owner].Name;
            }
            for (var j = 0; j < idsArr.length ; j++) {
                childrensArr[j] = albumRowObj[owner.toString() + idsArr[j].toString()];
            }

        } else {

            aomTypesString = AoMTypes[parseInt(aomType)].AssetPageTitle;
            if (idsArr.length > 1) ext = "s";

            if (viewer.ID.toString() == owner) {
                //title = idsArr.length + " new pictures";
                title = idsArr.length + " new " + aomTypesString + ext;
            } else {
                //title = idsArr.length + " pictures from " + ContactCloud[owner].Name;
                title = idsArr.length + " " +  aomTypesString + ext + " from " + ContactCloud[owner].Name;
            }

            for (var j = 0; j < idsArr.length ; j++) {
                childrensArr[j] = assetRowObj[owner.toString() + idsArr[j].toString()];
            }
        }

        // populate the main array
        newsFeedObj[i] = {ID: rowId, Title: title, Type: type, When: when, Owner: owner, AomType: aomType, children: childrensArr };
    }

    NewsFeed = newsFeedObj;
	NewsFeed.isLoaded = true;
}


function parseNewsFeedOnFailure(callbackData) {

	if (NewsFeed.numOfLoadingTries < Consts.ACTION_RETRIES)
	{
		NewsFeed.numOfLoadingTries++;
        executeWebRequest("Timelines.GetInboxEntities",[],{onSuccessFunction:parseNewsFeedOnSuccess, onFailureFunction:parseNewsFeedOnFailure}, undefined, callbackXml);
	}
}

// Contact Cloud handlers
function parseContactCloudOnSuccess(recievedData, callbackData)
{
  var targetID, name, targetTypeID, smallAvatarURL, avatarURL, email, birthDate, realGroup;
  var i, j, prop;
	
	// fill the current viewer (user) data
	viewer.ID = recievedData.Viewer.ID;
	
	// add the global targets to the cloud
	for (i = 0, j = recievedData.GlobalTargets.length; i < j; i++)
	{
		targetID = recievedData.GlobalTargets[i].ID;
		//name = recievedData.GlobalTargets[i].Name;
		//smallAvatarURL = recievedData.GlobalTargets[i].SmallAvatarURL;
		//avatarURL = recievedData.GlobalTargets[i].AvatarURL;
		
		switch (targetID)
		{
			case 1: 
			{
				targetTypeID = TargetTypes.PUBLIC;					
				break;
			}
			case 2:
			{
				targetTypeID = TargetTypes.NETWORK;					
				break;
			}
}
ContactCloud[targetID.toString()] = {
TargetTypeID: targetTypeID,
Name: recievedData.GlobalTargets[i].Name
};
		for (prop in recievedData.GlobalTargets[i])
		  ContactCloud[targetID.toString()][prop] = recievedData.GlobalTargets[i][prop];
		ContactCloud.isLoaded = true;
		ContactCloud.err = false;
	}

	// add the groups to the cloud
	for (i = 0, j = recievedData.Groups.length; i < j; i++) {
	  targetID = recievedData.Groups[i].ID.toString();
	  ContactCloud[targetID] = {
	    TargetTypeID: TargetTypes.GROUP,
	    Name: recievedData.Groups[i].FirstName + " " + recievedData.Groups[i].LastName
	  };
	  for (prop in recievedData.Groups[i])
	    ContactCloud[targetID][prop] = recievedData.Groups[i][prop];
	}
	
	// add the contacts to the cloud
	for (i = 0, j = recievedData.Contacts.length; i < j; i++) {
	  targetID = recievedData.Contacts[i].ID.toString();
	  ContactCloud[targetID] = {
	  TargetTypeID: TargetTypes.CONTACT,
	  Name: recievedData.Contacts[i].FirstName + " " + recievedData.Contacts[i].LastName
	  };
	  for (prop in recievedData.Contacts[i])
	    ContactCloud[targetID][prop] = recievedData.Contacts[i][prop];
	}

	// add the viewer
	ContactCloud[viewer.ID.toString()] = {
	TargetTypeID: TargetTypes.VIEWER,
	Name: recievedData.Viewer.FirstName + " " + recievedData.Viewer.LastName
	};
	for (prop in recievedData.Viewer)
	  ContactCloud[viewer.ID.toString()][prop] = recievedData.Viewer[prop];
}

function parseContactCloudOnFailure(callbackData){
  if (ContactCloud.numOfLoadingTries < Consts.ACTION_RETRIES) {
    ContactCloud.numOfLoadingTries++;
    executeWebRequest("Contacts.GetContactCloud", [{ name: "SerType", value: 2}], { onSuccessFunction: parseContactCloudOnSuccess, onFailureFunction: parseContactCloudOnFailure });
  } else {
    ContactCloud.isLoaded = true;
    ContactCloud.err = true;
  }
}

// parsing the contact cloud from an XML into the cache object
function parseContactCloudXML(XMLString)
{

	var targetID, name, targetTypeID, smallAvatarURL, avatarURL;
	var xmlDoc = getXMLDoc(XMLString);

	// fill the current viewer (user) data
	viewer.ID = xmlDoc.getElementsByTagName("Viewer")[0].getAttribute("ID");
	
	// add the global targets to the cloud
	var globalTargets = xmlDoc.getElementsByTagName("GlobalTarget");
	for (var i = 0, j = globalTargets.length; i < j; i++)
	{
		targetID = globalTargets[i].getAttribute("ID");
		name = globalTargets[i].getAttribute("Name");
		smallAvatarURL = globalTargets[i].getAttribute("SmallAvatarURL");
		avatarURL = globalTargets[i].getAttribute("AvatarURL");
		
		switch (targetID)
		{
			case 1: 
			{
				targetTypeID = TargetTypes.PUBLIC;					
				break;
			}
			case 2:
			{
				targetTypeID = TargetTypes.NETWORK;					
				break;
			}
		}
		
		ContactCloud[targetID.toString()] = {Name:name, TargetTypeID:targetTypeID, SmallAvatarURL:smallAvatarURL, AvatarURL:avatarURL};
	}
	
	// add the groups to the cloud
	var groups = xmlDoc.getElementsByTagName("Group");
	for (var i = 0, j = groups.length; i < j; i++)
	{
		targetID = groups[i].getAttribute("ID");
		targetTypeID = TargetTypes.GROUP;
		name = groups[i].getAttribute("Name");
		smallAvatarURL = groups[i].getAttribute("SmallAvatarURL");
		avatarURL = groups[i].getAttribute("AvatarURL");
		
		ContactCloud[targetID.toString()] = {Name:name, TargetTypeID:targetTypeID, SmallAvatarURL:smallAvatarURL, AvatarURL:avatarURL};
	}
	
	// add the contacts to the cloud
	var contacts = xmlDoc.getElementsByTagName("Contact");
	for (var i = 0, j = contacts.length; i < j; i++)
	{
		targetID = contacts[i].getAttribute("ID");
		targetTypeID = TargetTypes.CONTACT;
		name = contacts[i].getAttribute("FirstName") + " " + contacts[i].getAttribute("LastName");
		smallAvatarURL = contacts[i].getAttribute("SmallAvatarURL");
		avatarURL = contacts[i].getAttribute("AvatarURL");
		
		ContactCloud[targetID.toString()] = {Name:name, TargetTypeID:targetTypeID, SmallAvatarURL:smallAvatarURL, AvatarURL:avatarURL};
	}
}

function parseDefaultSharingOnSuccess(recievedData, callbackData)
{
	viewer.DefaultSharing = recievedData;
}

function parseDefaultSharingOnFailure(callbackData)
{
	if (viewer.numOfLoadingTries < Consts.ACTION_RETRIES)
	{
		viewer.numOfLoadingTries++;
		executeWebRequest("Sidebar.GetDefaultSharingLevel",[{name:"SerType", value:2}],{onSuccessFunction:parseDefaultSharingOnSuccess, onFailureFunction:parseDefaultSharingOnFailure});	
	}
}

// parse the branch data handlers
function parseBranchesOnSuccess(recievedData, callbackData)
{
	var title, childrenNum, imageClass, branchType;
			
	for (var i = 0, j = recievedData.length; i < j; i++)
	{
		branchType = recievedData[i].BranchType;
		title = recievedData[i].Title;
		childrenNum = recievedData[i].Children;
		
		// set the image class
		switch (branchType)
		{
			case 0:
			{
				imageClass = "AlbumsBranchImage";
				break;
			}
			case 1:
			{
				imageClass = "TagsBranchImage";
				break;
			}
			case 2:
			{
				imageClass = "SharedWithBranchImage";
				break;
			}
			case 3:
			{
				imageClass = "SourceBranchImage";
				break;
			}
			case 4:
			{
			    imageClass = "NewStuffBranchImage";
				break;
			}
		}
		
		var branch = new Branch(branchType, title, childrenNum, imageClass, branchType.toString(), branchType);
		cacheBranches[i] = branch;
		cacheDictionary[branchType.toString()] = branch;
	}
}

function parseBranchesOnFailure(callbackData)
{
	if (pendingAction.numOfRetries < Consts.ACTION_RETRIES)
	{
		pendingAction.numOfRetries++;
		executeWebRequest("Sidebar.GetBranches",[{name:"SerType", value:2}],{onSuccessFunction:parseBranchesOnSuccess, onFailureFunction:parseBranchesOnFailure});
	}
}

// parse Branch Containers handlers
// add the Containers recieved from server to the branch that requested it ("this" of the calling folder)
function parseBranchContainersOnSuccess(recievedData, callbackData) {

    var id, title, childrenNum, created, albumWhen, albumWhen, permission, iconURL, cacheID, container;	
	var branch = callbackData.branch;
	var childNum = branch.Children.length;

	// add the recieved containers to the branch's assets array
	if (branch.BranchType == BranchTypes.SHARED)
	{
	    for (var i = 0, j = recievedData.length; i < j; i++)
	    {
	        id = recievedData[i].ID;

	        if (id == viewer.ID)	// don't add current user to group list
	        {
	            branch.NumOfChildren = parseInt(branch.Children) - 1;
	        }
	        else {
	            if (ContactCloud[id])	// the contact cloud has the id
	            {
	                title = ContactCloud[id].Name;
	                childrenNum = recievedData[i].Children;
	                iconURL = ContactCloud[id].SmallAvatarURL;
	            }
	            else		// unknown contact
	            {
	                title = "Unknown";
	                childrenNum = '?';
	                iconURL = "";
	            }
	            cacheID = branch.CacheID.toString() + id.toString();

	            // check if the container already exists
	            container = cacheDictionary[cacheID];
	            if (!container) {
	                container = new Container(id, title, childrenNum, iconURL, created, albumWhen, permission, cacheID, branch.BranchType, branch);
	                branch.Children[branch.Children.length] = container;
	                cacheDictionary[cacheID] = container;
	            }
	            else {
	                container.update(id, title, childrenNum, iconURL, created, albumWhen, permission, cacheID, branch.BranchType, branch);
	            }
	        }
	    }
	}
	else
	{
	    for (var i = 0, j = recievedData.length; i < j; i++)
	    {
	        id = recievedData[i].ID;
	        title = recievedData[i].Title;
	        childrenNum = recievedData[i].Children;
	        created = recievedData[i].Created;
	        albumWhen = recievedData[i].AlbumWhen;

	        if ("Perm" in recievedData[i])
	            permission = recievedData[i].Perm;
	        iconURL = recievedData[i].IconURL;
	        cacheID = branch.CacheID.toString() + id.toString();

	        // check if the container already exists
	        container = cacheDictionary[cacheID];
	        if (!container) {
	            container = new Container(id, title, childrenNum, iconURL, created, albumWhen, permission, cacheID, branch.BranchType, branch);
	            branch.Children[branch.Children.length] = container;
	            cacheDictionary[cacheID] = container;
	        }
	        else {
	            container.update(id, title, childrenNum, iconURL, created, albumWhen, permission, cacheID, branch.BranchType, branch);
	        }
	    }
	}

	// check if got the last containers in the branch
	if (recievedData.length < Consts.LOAD_AMOUNT)	
	{		
		branch.IsFull = true;
		// update the number of children of branch in case it was not correct
		branch.NumOfChildren = branch.Children.length;				
	}
	
	// update the number of children of branch in case we loaded more than the original number untill now
	if (branch.Children.length > branch.NumOfChildren)
		branch.NumOfChildren = branch.Children.length;
	
	branch.IsLoading = false;
	branch.LoadingRetries = 0;
	branch.LoadingError = false;
}

// parse Branch Containers handlers
// add the Containers recieved from server to the branch that requested it ("this" of the calling folder)
function parseBranchXmlContainersOnSuccess(recievedData, callbackData)
{

    var NewsFeedRows = recievedData.documentElement.getElementsByTagName('NewsFeed')[0].getElementsByTagName('Rows')[0].getElementsByTagName('Row')
    
    var id, title, childrenNum, created, albumWhen, albumWhen, permission, iconURL, cacheID, container;	
	var branch = callbackData.branch;
	var childNum = branch.Children.length;
	
	// add the recieved containers to the branch's assets array
	for (var i = 0, j = NewsFeedRows.length; i < j; i++)
	{
        Ids = NewsFeedRows[i].getAttribute('Ids');
        userId = NewsFeedRows[i].getAttribute('Owner');
        aomType = NewsFeedRows[i].getAttribute('AomType');
        type = NewsFeedRows[i].getAttribute('type')
        when = NewsFeedRows[i].getAttribute('When')

		// check if the container already exists
		container = cacheDictionary[cacheID];
		if (!container)
		{												
			container = new Container(id, title, childrenNum, iconURL, created, albumWhen, permission, cacheID, branch.BranchType, branch);
			branch.Children[branch.Children.length] = container;
			cacheDictionary[cacheID] = container;
		}
		else
		{
			container.update(id, title, childrenNum, iconURL, created, albumWhen, permission, cacheID, branch.BranchType, branch);
		}
	}
	
	// check if got the last containers in the branch
	if (recievedData.length < Consts.LOAD_AMOUNT)	
	{		
		branch.IsFull = true;
		// update the number of children of branch in case it was not correct
		branch.NumOfChildren = branch.Children.length;				
	}	
	// update the number of children of branch in case we loaded more than the original number untill now
	if (branch.Children.length > branch.NumOfChildren)
	{
		branch.NumOfChildren = branch.Children.length;
	}
		
	branch.IsLoading = false;
	branch.LoadingRetries = 0;
	branch.LoadingError = false;
}


function parseBranchContainersOnFailure(callbackData)
{
	var branch = callbackData.branch;
	
	branch.IsLoading = false;
	branch.LoadingRetries++;
	branch.LoadingError = true;
}

// parse Container Assets handlers
// add the assets recieved from server to the container that requested it ("this" of the calling folder)
function parseContainerAssetsOnSuccess(recievedData, callbackData)
{

	var id, title, created, defaultIconURL, iconURL, description, permission, creator, tagCreator, width, height, cacheID, aomTypeID, aomType, itemType;
	var branch = callbackData.branch;
	var container = callbackData.container;
	var childNum = container.Children.length;
	
	// add the recieved assets to the container's assets array
	for (var i = 0, j = recievedData.length; i < j; i++)
	{
		id = recievedData[i].ID;
		cacheID = container.CacheID.toString() + id.toString();
		
		title = recievedData[i].Title;
		created = recievedData[i].Created;
		defaultIconURL = recievedData[i].IconURL; 
		iconURL = recievedData[i].IconURL;		
		creator = recievedData[i].Creator;			
		tagCreator = recievedData[i].TagCreator;						
		width = recievedData[i].TimelineWidth;
		height = recievedData[i].TimelineHeight;
		description = "";


		//debugger;

		aomTypeID = recievedData[i].AoMTypeID; // AoMType for the description and iconURL

		if (aomTypeID == 0)		// for subjects in the "Shared With" groups conatainer which aren't assets
		{
			switch (recievedData[i].Type)
			{
				case "Timeline":
				{
				    itemType = ItemTypes.TIMELINE;
				    description = recievedData[i].Type;					
					break;
				}
				case "Album":
				{
				    itemType = ItemTypes.ALBUM;
				    description = recievedData[i].Type;					
					break;
				}
				default:
				{
				    itemType = ItemTypes.ASSET;
				    aomType = AoMTypes[aomTypeID];
				    if (aomType) {
				        description = aomType.Description;
				        defaultIconURL = aomType.SidebarIconURL;
				        if (!aomType.UseThumb || iconURL == "")
				            iconURL = aomType.SidebarIconURL;
				    }
				}
			}
			
			//description = recievedData[i].Type;
		}
		else
		{
			itemType = ItemTypes.ASSET;
			aomType = AoMTypes[aomTypeID];	
			if (aomType)
			{		
				description = aomType.Description;
				defaultIconURL = aomType.SidebarIconURL;
				if (!aomType.UseThumb || iconURL == "")
					iconURL = aomType.SidebarIconURL;
			}
		}

		
		if ("Perm" in recievedData[i])
			permission = recievedData[i].Perm;
				
		// first check if the asset already exists in cache.
		// because the timeline / album / asset don't have unique id if type is "album" / "timeline" - 
		// the key in the "assets" object is id + itemType
		asset = assets[id];

		if (!asset)	// asset isn't in cache at all - create new asset object
		{
			var asset = new Asset(id, title, defaultIconURL, iconURL, created, itemType, description, permission, creator, tagCreator, width, height, aomTypeID);
			asset.ContainerCacheIDs[asset.ContainerCacheIDs.length] = container.CacheID;
			asset.AssetCacheIDs[asset.AssetCacheIDs.length] = cacheID;
			
			assets[id] = asset;

			var cacheAsset = new CacheAsset(cacheID, asset);
			container.Children[container.Children.length] = cacheAsset;
			cacheDictionary[cacheID] = cacheAsset;
		}
		else	// asset is in cache
		{
			// check if there's a CacheAsset object in this container
			if (cacheDictionary[cacheID])
			{
				// update the asset data
				asset.update(id, title, defaultIconURL, iconURL, created, itemType, description, permission, creator, tagCreator, width, height, aomTypeID);
			}
			else
			{
				asset.ContainerCacheIDs[asset.ContainerCacheIDs.length] = container.CacheID;
				asset.AssetCacheIDs[asset.AssetCacheIDs.length] = cacheID;
				var cacheAsset = new CacheAsset(cacheID, asset);
				container.Children[container.Children.length] = cacheAsset;
				cacheDictionary[cacheID] = cacheAsset;
			}
		}
	}

	// check if got the last assets in the container
	if (recievedData.length < Consts.LOAD_AMOUNT)
	{
		container.IsFull = true;
		// update the number of children of container in case it was not correct
		container.NumOfChildren = container.Children.length;
	}		
	
	// update the number of children of container in case we loaded more than the original number untill now
	if (container.Children.length > container.NumOfChildren)
		container.NumOfChildren = container.Children.length;	
		
	container.IsLoading = false;
	container.LoadingRetries = 0;			
}

function parseContainerAssetsOnFailure(callbackData)
{
	var container = callbackData.container;
	
	container.IsLoading = false;
	container.LoadingRetries++;
}


/***		action handlers		***/

// handler for all actions that fail
function actionOnFailure(callbackData)
{
	if (pendingAction.numOfRetries < Consts.ACTION_RETRIES)
	{
		pendingAction.numOfRetries++;				
		executeWebRequest(pendingAction.functionName, pendingAction.functionParams, pendingAction.callbackData);
	}
	else		// after 3 retries - release the sidebar from the action lock and hide the waiting window
	{
		// check if there's a pending timeout function on the loading image and clear it
		var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
		if (timerID != undefined)
		{
			clearTimeout(timerID);
		}
		
		pendingAction.pending = false;
		$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
	}	
}

// after placing assets on Timeline - jump to the first asset
function PlaceOnTimelineOnSuccess(recievedData, callbackData)
{

	// get the asset / album ID from the function Params
	var params = pendingAction.functionParams;
	
	// call the flash method 
	if (params[0].name == 'AlbumID') 
	{
	    var albumArr = new Array();
        albumArr.push(getAlbumById(params[0].value));
    	flash.placeAlbumOnTimeline(albumArr);
    } 
	else 
	{
        var selectedItemsString = params[0].value;	
	    var assets = getAssetsByIds(selectedItemsString);
    	flash.placeAssetOnTimeline(assets);
	}
	

	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
		
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
}

// get the list of targets sharing the item/s and check them in the sharing window
function GetSharingTargetsOnSuccess(recievedData, callbackData)
{	
	// mark as selected the target elements that share this item
	
	
	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
	
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
}

function makePrivateOnSuccess(recievedData, callbackData)
{
	// update the cache and GUI - removing the sharing from all targets
	
	
	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
	
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
}

// Simple share handler
function SimpleShareOnSuccess(recievedData, callbackData)
{
	// update the cache and GUI with the changes
	
	
	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
	
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
}

// tag handler
function tagOnSuccess(recievedData, callbackData)
{
	// update the cache and GUI with the changes
	var chosenTags = callbackData.chosenTags;
	var cacheIDs = callbackData.cacheIDs.split(",");
	var tagObjects;
	if (cacheBranches.length){ // Sidebar is active
	  // find the Tag cache object
	  for (i = 0, j = cacheBranches.length; i < j; i++)
	  {
		  if (cacheBranches[i].BranchType == BranchTypes.TAG)
		  {
			  tagObjects = cacheBranches[i].Children;
			  break;
		  }
	  }
	
	  // search for the tags in cache and if found - clear their assets for getting updated data from server
	  for (var i = 0, j = chosenTags.length; i < j; i++)
	  {
		  for (var x = 0, z = tagObjects.length; x < z; x++)
		  {
			  if (tagObjects[x].Title == chosenTags[i])
			  {
				  tagObjects[x].addAssets(cacheIDs);
			  }
		  }
	  }
	}
	
	switch(callbackData.callerNameSpace){
	  case "AssetPage":
	    // Asset Page specific update:
	    assetPage.controls.tag.specialFunction('update_tags', recievedData);
      break;
  }
	
	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
	
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
}

// add to handler
function addToContainerOnSuccess(recievedData, callbackData)
{
	// update the cache and GUI with the changes
	var container = callbackData.container;
	var cacheIDs = callbackData.cacheIDs.split(",");
	
	container.addAssets(cacheIDs);
	
	// call Timeline flash API function only for adding assets to album
	if (container.BranchType == BranchTypes.ALBUM)
	{
	    var params = pendingAction.functionParams;
		var album = getAlbumById(params[0].value);		
		var assets = getAssetsByIds(params[1].value);
		flash.addAssetsToAlbum(album, assets);
	}
	
	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
	
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
}

// remove from container handler
function removeFromContainerOnSuccess(recievedData, callbackData)
{
	// update the cache and GUI with the changes
	var container = callbackData.container;
	var cacheIDs = callbackData.cacheIDs.split(",");
	
	container.removeAssets(cacheIDs);
	
	// call Timeline flash API function only for adding assets to album
	if (container.BranchType == BranchTypes.ALBUM)
	{
	    var params = pendingAction.functionParams;
		var album = getAlbumById(params[0].value);		
		var assets = getAssetsByIds(params[1].value);
		flash.removeAssetsFromAlbum(album, assets);
	}
	
	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
	
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
}

// Rename handler
function renameOnSuccess(recievedData, callbackData)
{
	// get the data of the change fom the function parameters
	var params = pendingAction.functionParams;
	var cacheID = callbackData.cacheID;
	var selectedAll = callbackData.selectedAll;
	var itemID = params[0].value;
	var newName = params[1].value; 
	
	if (selectedAll)		// change the album name in cache
	{
		var container = cacheDictionary[cacheID];
		
		// if found the album in the cache
		if (container)		
		{
		
        	// call the flash method 
	        var albumObj = getAlbumById(container.ID);
            flash.renameAlbum(albumObj,newName);
		
			container.rename(newName);
		}
		
		// now look for the album in the "Shared With" branch assets which can also be albums
		albumAsset = assets[container.ID];
		if (albumAsset)
		{
			albumAsset.rename(newName);
		}
	}
	else	// change the asset name everywhere it appears in cache
	{
		var asset = cacheDictionary[cacheID].AssetObject;
		
		asset.rename(newName);
		
		// check if the asset is album and change the album in the "Albums" branch
		if (asset.Type == ItemTypes.ALBUM)
		{
			var albumsCacheID;
			
			// find the Albums cache object	
			for (var i = 0, j = cacheBranches.length; i < j; i++)
			{
				if (cacheBranches[i].BranchType == BranchTypes.ALBUM)
				{
					albumsCacheID = cacheBranches[i].CacheID;
					break;
				}
			}
			
			// get the container object and change its name
			var container = cacheDictionary[albumsCacheID + asset.ID];
			if (container)
				container.rename(newName);
		}

    	// call the flash method 
    	var asset = getAssetById(itemID);
    	flash.renameAsset(asset, newName);
	}
	
	
	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
	
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';		
}

function deleteOnSuccess(recievedData, callbackData)
{
	// update the cache and GUI with the changes
	var cacheIDs = callbackData.cacheIDs.split(",");
	var selectedAll = callbackData.selectedAll;
	var params = pendingAction.functionParams;
	var itemIDs = params[0].value;
	    
	if (selectedAll)		// delete album
	{
		var container = cacheDictionary[cacheIDs];
		
		// if found the album in the cache
		if (container)		
		{
            // call flash method
	        var albumArr = new Array();
            albumArr.push(getAlbumById(container.ID));
            flash.deleteAlbums(albumArr)
		
			container.deleteContainer();
		}
		
		// now look for the album in the "Shared With" branch assets which can also be albums
		albumAsset = assets[container.ID];
		if (albumAsset)
		{
            // call flash method
            flash.deleteAlbum(albumAsset)
		
			albumAsset.deleteAsset();
		}
	}
	else	// delete the asset everywhere it appears in cache
	{

    	var assetsToDelete = new Array(); // array of objext for the flash

		for (var i = 0, j = cacheIDs.length; i < j; i++)
		{
			var asset = cacheDictionary[cacheIDs[i]].AssetObject;						
			
			// check if the asset is album and change the album in the "Albums" branch
			if (asset.Type == ItemTypes.ALBUM)
			{
				var albumsCacheID;
				
				// find the Albums cache object	
				for (var x = 0, z = cacheBranches.length; x < z; x++)
				{
					if (cacheBranches[x].BranchType == BranchTypes.ALBUM)
					{
						albumsCacheID = cacheBranches[x].CacheID;
						break;
					}
				}
				
				// get the container object and change its name
				var container = cacheDictionary[albumsCacheID + asset.ID];
				if (container) 
				{
					container.deleteContainer();
				}
			}
			assetsToDelete.push(asset);
			asset.deleteAsset();
		}
	    // call flash method
	    flash.deleteAssets(assetsToDelete);
	}
	
	// check if there's a pending timeout function on the loading image and clear it
	var timerID = LoadingTimers[callbackData.callerNameSpace + '_ProcessingAction'];
	if (timerID != undefined)
	{
		clearTimeout(timerID);
	}
	
	// release the sidebar from the action lock and hide the waiting window
	pendingAction.pending = false;
	$get(callbackData.callerNameSpace + '_ProcessingAction').style.display = 'none';
}