/*
 * Image Browser. 
 *
 * TODO:
 *   refactor delete, markmain, approve request from get to post.
 */
dojo.require("dojo.debug");
dojo.require("dojo.string.*");
dojo.require("dojo.io.*");
dojo.require("dojo.lfx.*");
dojo.require("dojo.event.*");
dojo.require("dojo.collections.ArrayList");
dojo.require("dojo.collections.Dictionary");

/* Template is like

  <div id='image_browser' class='image_browser'>
    <ul id='image_browser_bar'>
      ...
    </ul>
    <a href=''><img id='image_browser_main_image' src='' /></a>
    <ul id='image_browser_list'>
      <li><a href=''><img id='' /></a></li>
    </ul>
  </div>

*/

/* 
 * Image Data Class
 *
 * url:  image url of the img, '/images/example.png'.
 * smallSize: thumbnail size, [width, height].
 * bigSize:   main image size,  [width, height].
 * actions:    supported action keyworks, ['markmain', 'add', 'delete'].
 */
function ImageData(id, url, smallUrl, bigUrl, smallSize, bigSize, actions, title) {
    this.id = id;
    this.url = url;
    this.smallUrl = smallUrl;
    this.bigUrl = bigUrl;
    this.smallSize = smallSize;
    this.bigSize = bigSize;
    this.actions = new dojo.collections.ArrayList();
    this.actions.addRange(actions);
    this.title = title;
    this.disableEnlarge = false;
}

// helper mehtod: turn json object to ImageData instance
ImageData.createFromObject = function(obj) {
    return new ImageData(obj.id,
			 obj.url,
			 obj.smallUrl,
			 obj.bigUrl,
			 obj.smallSize,
			 obj.bigSize,
			 obj.actions,
			 obj.title);
};
   
/*
 * Image Browser Controller
 *
 * actionDict, key is action name, value is the action handler.
 * 
 */
function ImageBrowser(actionDict, getListUrl, getMainUrl, defaultImageData) {
    // Data
    dojo.debug('Image Browser Init Data.');
    this.list = new dojo.collections.ArrayList();
    this.current = null;
    this.getListUrl = getListUrl;
    this.getMainUrl = getMainUrl;
    this.defaultImageData = defaultImageData;
    this.actionDict = actionDict;
    var action_keys = actionDict.getKeyList();
    for (var i=0; i<action_keys.length; i++){
	var action = action_keys[i];
	var tag = dojo.byId('ib_action_' + action);
	var handler = actionDict.item(action);
	if (handler) {
	    handler.imagebrowser = this;
	    dojo.event.connect(tag, 'onclick', handler, 'handler');
	}
    }
    
    // Display tag
    dojo.debug('Image Browser Init Display');
    this.containerTag = dojo.byId('ib');
    this.listTag = dojo.byId('ib_list');
    this.toolbarTag = dojo.byId('ib_toolbar');
    this.currentLinkTag = dojo.byId('ib_current_link');
    this.currentImageTag = dojo.byId('ib_current_image');
    this.currentTitleTag = dojo.byId('ib_current_title');
    dojo.debug('Image Browser Init Display stop.');

    this.createThumbnailTag = function(imageData) {
	dojo.debug('createThumbnailTag');
	// update display <li id="image_id"><a><img src='smallUrl' /></a></li>
	var li = document.createElement('li');
	li.id = 'ib_thumbnail_' + imageData.id;
	var a = document.createElement('a');
	a.href = '.';
	var img = document.createElement('img');
	img.src = imageData.smallUrl;
	img.title = imageData.title;
	img.alt = img.title;
	a.appendChild(img);
	li.appendChild(a);
	var imagebrowser = this;
	// event connect
	callback = {
	    'imagebrowser': imagebrowser,
	    'imageData': imageData,
	    'setCurrent': function(e){
		e.preventDefault();
		this.imagebrowser.setCurrent(this.imageData);
	    }
	}
	dojo.event.connect(a, 'onclick', callback, 'setCurrent');
	return li;
    };
    dojo.debug('createThumbnailTag build');

    /* Append image data to the list. */
    this.append = function(imageData) {
	dojo.debug('append');
	this.list.add(imageData); // Update Data
	var li = this.createThumbnailTag(imageData); // Update UI
	this.listTag.appendChild(li);
	this.updateListDisplay();
    };

    dojo.debug('append build');

    this.updateListDisplay = function() {
	this.listTag.style.display = this.list.count>1? "block": "none";
    }

    this.remove = function(imageData) {
	dojo.debug('remove');
	for(var i=0; i<this.list.count; i++) {
	    var img = this.list.item(i);
	    dojo.debug(img.id);
	    if(img.id == imageData.id) {
		this.list.remove(img);
		break;
	    }
	}
	this.updateListDisplay();
	var li = dojo.byId('ib_thumbnail_' + imageData.id);
	// squeeze nodes and fade
	var anim = dojo.lfx.propertyAnimation(
	    [li.id],
	    [{ property: "height", end:1},
	     { property: "opacity", end: 0},
             { property: "top", end: 0},
             { property: "left", end: 0},
             { property: "width", end: 0}],
	    1000,
	    dojo.lfx.easeInOut).play(1000);
	dojo.debug('remove anim');
	var onEnd = {
	    'li': li,
	    callback: function(){ 
		this.li.parentNode.removeChild(this.li);
	    } 
	}
	dojo.event.connect(anim, "onEnd", onEnd, 'callback');
    };
    
    dojo.debug('remove build');

    this.setCurrent = function(imageData) {
	dojo.debug('setCurrent');
	this.current = imageData;
	this.currentLinkTag.href = imageData.url;
	this.currentLinkTag.target = '_blank';
	var self = this;
	dojo.event.connect(this.currentLinkTag,
			   'onclick',
			   function(evt) { 
			       if (self.current.disableEnlarge) {
				   evt.preventDefault();
				   popup_win(self.addImageUrl, 900, 600);
			       }
			   });
	this.currentImageTag.alt = imageData.title;
	this.currentImageTag.title = imageData.title;
	this.currentImageTag.src = "";
	this.currentImageTag.src = imageData.bigUrl;
	this.currentTitleTag.innerHTML = imageData.title;

	var action_keys = this.actionDict.getKeyList();
	var show_toolbar = false;
	for (var i=0; i<action_keys.length; i++){
	    var action = action_keys[i];
	    var tag = dojo.byId('ib_action_' + action);
	    if (imageData.actions.contains(action)) {
		dojo.debug(action);
		show_toolbar = true;
		tag.parentNode.style.display = 'inline';
	    } else {
		tag.parentNode.style.display = 'none';
	    }
	}
	this.toolbarTag.style.display = show_toolbar? 'block' : 'none';
    };

    dojo.debug('setCurrent build');

    this.update = function(id, imageData) {
	var img = null;
	for(var i=0; i<this.list.count; i++) {
	    img = this.list.item(i);
	    dojo.debug(img.id);
	    if(img.id == id) {
		this.list.insert(i, imageData);
		this.list.remove(img);
		var li = this.createThumbnailTag(imageData);
		var oldLi = dojo.byId('ib_thumbnail_' + imageData.id);
		oldLi.parentNode.replaceChild(li,oldLi);
		break;
	    }
	}
    };

    dojo.debug('update build');

    this.loadImageListFromUrl = function() {
	dojo.debug('loadImageListFromUrl');
	var imagebrowser = this;
	var getImageListRequest = {
	    url: imagebrowser.getListUrl,
	    mimetype: "text/json",
	    error: function(type, errObj){
		alert("Can't load image list.");
	    },
	    load: function(type, data, evt){
		dojo.debug('loadImageListFromUrl Callback');
		dojo.debug(data.length);
		dojo.debug(data);
		for(var i=0; i<data.length; i++){
		    var imageData = ImageData.createFromObject(data[i]);
		    imagebrowser.append(imageData);
		}
		imagebrowser.setMainImageFromUrl();
	    }
	};
	dojo.io.bind(getImageListRequest);
    };

    dojo.debug('loadImageListFromUrl build');

    this.setMainImageFromUrl = function() {
	/*
	 * warning: ensure that image is/will be in list already.
	 */
	dojo.debug('setMainImageFromUrl');
	var imagebrowser = this;
	var getMainImageRequest = {
	    url: imagebrowser.getMainUrl,
	    mimetype: "text/json",
	    error: function(type, errObj){
		alert("Can't load main image.");
	    },
	    load: function(type, data, evt){
		var imageData = null;
		if (data) {  //has mainImage
		    dojo.debug('has MainImage');
		    imageData = ImageData.createFromObject(data);
		}
		else if (imagebrowser.list.count>0){ //try use the first image as the main image.
		    imageData = imagebrowser.list.item(0);
		    dojo.debug('use first image as the main image');
		}
		if (imageData) {
		    imagebrowser.setCurrent(imageData);
		} else if (imagebrowser.defaultImageData){
		    imagebrowser.setCurrent(imagebrowser.defaultImageData);
		} else { // no any thumbnails and no default image, hide whole tag.
		    imagebrowser.containerTag.style.display = "none";
		}
	    }
	};
	dojo.io.bind(getMainImageRequest);
    };

    dojo.debug('setMainImageFromUrl build');
}

/*
 * Action Handlers
 *
 * Handler is a object with a 'handler' method.
 * Each Handler will register to ImageBrowserController Manually.
 * this.imagebrowser will point to the registered ImageBrowserController.
 */

var deleteImageHandler = {}; // delete image.
deleteImageHandler.handler = function (e){
    dojo.debug('deleteImageHandler');
    e.preventDefault();
    var imagebrowser = this.imagebrowser;
    var url = '/images.delete/' + imagebrowser.current.id + '/';
    if (imagebrowser.list.count == 1) {
	if (! confirm(gettext("You are going to delete the last image, please make sure to upload at least one image.\nDo you want to delete this image?"))) {
		return;
	}
    } else {
	if (! confirm(gettext("Do you want to delete this image?"))) {
		return;
	}
    }
    
    showWaitingDialog('delete...');
    dojo.debug(url);
    var req = {
	url: url,
	mimetype: "text/json",
	error: function(type, errObj){
	    alert("Can't delete image.");
	    hideWaitingDialog();
	},
	load: function(type, data, evt){
	    if (data) {
		dojo.debug('deleteImageHandler callback');
		hideWaitingDialog();
		imagebrowser.remove(imagebrowser.current);
		imagebrowser.setMainImageFromUrl();
		dojo.debug('deleteImageHandler callback End');
	    } else {
		alert('Failed, do you have permission?');
	    }
	}
    };
    dojo.io.bind(req);
};

function ApproveImageHandler(value){ // Approve/Unapprove image.
    this.value = value
    this.handler = function(e) {
	e.preventDefault();
	var imagebrowser = this.imagebrowser;
	var url = '/images.approve/' + imagebrowser.current.id + '/' + this.value + '/';
	showWaitingDialog('submiting...');
	dojo.debug(url);
	var req = {
	    url: url,
	    mimetype: "text/json",
	    error: function(type, errObj){
		alert("Can't approve image.");
	    },
	    load: function(type, data, evt){
		if (data) {
		    hideWaitingDialog();
		    var imageData = ImageData.createFromObject(data);
		    imagebrowser.update(imagebrowser.current.id, imageData);
		    dojo.debug(imageData.actions);
		    imagebrowser.setCurrent(imageData); 
		} else {
		    alert('Failed, do you have permission?');
		}
	    }
	};
	dojo.io.bind(req);
    };
}
approveImageHandler = new ApproveImageHandler(1);
unapproveImageHandler = new ApproveImageHandler(0);

markmainImageHandler = {}; // markmian Image
markmainImageHandler.handler = function (e) {
    e.preventDefault();
    var imagebrowser = this.imagebrowser;
    var url = '/images.markmain/' + imagebrowser.current.id + '/';
    showWaitingDialog('submiting...');
    dojo.debug(url);
    var req = {
	url: url,
	mimetype: "text/json",
	error: function(type, errObj){
	    alert("Server Error.");
	},
	load: function(type, data, evt){
	    if (data) {
		hideWaitingDialog();
		dojo.debug('markmain');
	    } else {
		alert('Failed, do you have permission?');
	    }
	}
    };
    dojo.debug('req ready');
    dojo.io.bind(req);
};

/*
 * Helper method for add new image. Called from popup window.
 */
appendImageFromUrl = function(url) {
    var imagebrowser = ib; // use global instance
    showWaitingDialog('loading...');
    var req = {
	url: url,
	mimetype: "text/json",
	error: function(type, errObj){
	    hideWaitingDialog();
	    alert("Can't load image: " + url);
	},
	load: function(type, data, evt){
	    window.popup.close();
	    window.popup = null;
	    var imageData = ImageData.createFromObject(data);
	    imagebrowser.append(imageData);
	    imagebrowser.setCurrent(imageData);
	    hideWaitingDialog();
	}
    };
    dojo.io.bind(req);
};

var ib=null;

function ib_testvar() {
    var actionDict= new dojo.collections.Dictionary();
    actionDict.add('add', null);
    actionDict.add('delete', deleteImageHandler);
    actionDict.add('approve', approveImageHandler);
    actionDict.add('unapprove', unapproveImageHandler);
    actionDict.add('markmain', markmainImageHandler);
    dojo.debug(actionDict);
    var obj = dojo.byId('ib_content_object');
    var data = dojo.string.trim(obj.innerHTML).split(':');
    var ctype = data[0];
    var oid = data[1];
    var getListUrl = "/images.get_list/"+ctype+'/'+oid+'/';
    var getMainUrl = "/images.get_main/"+ctype+'/'+oid+'/';
    var defaultUrl = '/images.get_default/'+ctype+'/'+oid+'/';
    var addImageUrl = "/images.add/"+ctype+'/'+oid+'/';
    /*    var defaultImageData = new ImageData(
	'', '', '',
	'/static/images/default-photo.png', 
	[76, 76], [485, 485], ['add'], '');
	defaultImageData.disableEnlarge = true;*/
    dojo.debug(getListUrl);
    dojo.debug(getMainUrl);
    dojo.debug(defaultUrl);
    //    dojo.debug(defaultImageData);
    var req = {
	url: defaultUrl,
	mimetype: "text/json",
	error: function(type, errObj){
	    alert("Can't load default image: " + defaultUrl);
	},
	load: function(type, data, evt){
	    var defaultImageData = null;
	    if (data) {
		defaultImageData = ImageData.createFromObject(data);
		defaultImageData.disableEnlarge = true;
	    }
	    ib = new ImageBrowser(
		    actionDict,
		    getListUrl,
		    getMainUrl,
		    defaultImageData);
	    dojo.debug('ib instance initial');
	    ib.loadImageListFromUrl();
	    ib.addImageUrl = addImageUrl;
	}
    };
    dojo.io.bind(req);
}

dojo.addOnLoad(ib_testvar);

