/**
 * UnsubscribeModule 
 * @author Jae Cho
 * Subclass of Module that represents user's friends
 */
function UploadModule() {

    this._cont = null;

    this._name = UploadModule.NAME;

    this._MAX_WIDTH = 300;

    this._MAX_HEIGHT = 300;

    /** callback method to call when completed */
    this._callback = null;

    this._cropCoord = null;

    this.initialize = function() { };

    this.setCallback = function(callback) {
        this._callback = callback;
    };

    /** @param title - optional title for the dialog */
    this.showUploadDialog = function(title)
    {
        this._initDialogsIfNeeded();
        this._clearData();

        if (title) this._cont.find("#umUploadDlgTitle").html(title);

        var uid = this._page.getLoggedInUserId();
        this._cont.find("#umProfilePic").attr("src",
                ProfileUtil.getImg({userId:uid, size:"big"}));

        this._displayDialog(this._uploadDlgControl);
    };    

    /**
     * since this module is not likely to be used for most of time, initialize only if needed
     */
    this._initDialogsIfNeeded = function() {

        if (this._cont) return;
        this._cont = $("#uploadModule");

        this._uploadDlg = this._cont.find("#umUploadDialog");
        this._waitDlg = this._cont.find("#umWaitDialog");
        this._cropDlg = this._cont.find("#umCropDialog");

        this._uploadDlgControl = new DialogControl("#umUploadDialog");
        this._waitDlgControl = new DialogControl("#umWaitDialog");
        this._cropDlgControl = new DialogControl("#umCropDialog");

        this._uploadForm = this._cont.find("#umUploadForm");

        this._cont.find("#umUploadBtn").bind("click", this, function(e) {
            e.preventDefault();
            var module = e.data;

            var value = module._uploadDlg.find("#umUploadInput").val();
            if (!value) {
                module._uploadDlg.find(".error_msg")
                        .html("Please select an image to upload")
                        .css("display", "block");
                return;
            }
            
            module._displayDialog(module._waitDlgControl);
            module._uploadForm.attr("action", "/dynamic/photo/scratch/upload");
            var options = { "success" : bindContext(module, module._handleUploadFormResponse) };
            module._uploadForm.ajaxSubmit(options);
            return false;
        });

        this._cont.find("#umCancelBtn").bind("click", this, function(e) {
            e.preventDefault();
            var module = e.data;
            module._displayDialog(null);
        });

        this._cont.find("#umApplyCropBtn").bind("click", this, function(e) {
            e.preventDefault();
            var module = e.data;
            module._submitCrop();
        });

        this._cont.find("#umCancelUploadBtn").bind("click", this, function(e) {
            e.preventDefault();
            var module = e.data;
            module._displayDialog(null);
        });

        this._cont.find("#umCancelCropBtn").bind("click", this, function(e) {
            e.preventDefault();
            var module = e.data;
            module._displayDialog(null);
        });

        this._cont.find("#umBackCropLink").bind("click", this, function(e) {
            e.preventDefault();
            var module = e.data;
            module._displayDialog(module._uploadDlgControl);
        });

        this._previewHeight = parseInt(this._cont.find("#umCropPreviewCover").css("height"));
        this._previewWidth = parseInt(this._cont.find("#umCropPreviewCover").css("width"));
        this._previewPic = this._cont.find("#umCropPreviewPic");
    };

    this._clearData = function() {
        this._uploadDlg.find(".error_msg").empty().css("display", "none");
        this._uploadDlg.find("#umUploadInput").val(null);
    };


    this._displayDialog = function(dlg){
        if (dlg != this._uploadDlgControl) this._uploadDlgControl.hideDialog();
        if (dlg != this._waitDlgControl) this._waitDlgControl.hideDialog();
        if (dlg != this._cropDlgControl) this._cropDlgControl.hideDialog();
        if (dlg) dlg.showDialog();
    };

    this._handleUploadFormResponse = function(responseText)
    {
        /** depending on the browser, responseText is either <pre>OK</pre> or OK -
         * so we do some work around here to check status */
        var errorMsg = null;
        if (!responseText) {
            errorMsg = "There was an error with the request. Please try later.";

        } else if (responseText.indexOf("UnsupportedFileSize") != -1) {
            errorMsg = "Your picture was not accepted.  The file must be no larger than 1 MB.  " +
                       "Please try again";
        } else if (responseText.indexOf("UnsupportedFileFormat") != -1) {
            errorMsg = "Your picture was not accepted.  The file must be in JPG, GIF, or PNG format. " +
                       "Please try again";
        } else if (responseText.indexOf("OK") < 0) {
            errorMsg = "There was a problem with your image. Please try different image."; 
        }

        if (errorMsg) {
            this._displayDialog(this._uploadDlgControl);
            this._uploadDlg.find(".error_msg")
                    .css("display", "block")
                    .html(errorMsg);
            return;
        }

        var downloadPath = "/dynamic/photo/scratch/download?time=" + (new Date()).getTime();

        // we rely on Image object so that we can get the actual image size after it is loaded
        this._newImg = new Image();
        this._newImg.onload = bindContext(this, this._initCrop);
        this._newImg.src = downloadPath;

        // empty these the container and re-create the image
        // we do this because Jcrop seem to linger around when user reopens the diaog
        var imgCont = this._cont.find("#umCropMainPicCover");
        imgCont.empty();

        this._cropImg = imgCont.append("<img/>").children("img");
        this._cropImg.attr("src", downloadPath);

    };

    this._initCrop = function()
    {
        // get the actual image size
        this._previewPic.attr("src", this._newImg.src);
        this._natHeight = this._newImg.height;
        this._natWidth = this._newImg.width;
        this._displayDialog(this._cropDlgControl);

        var sel = new Object();

        var imgRatio = this._natWidth / this._natHeight;
        var imgAreaRatio = this._MAX_WIDTH / this._MAX_HEIGHT;
        var zoom = imgRatio > imgAreaRatio ? this._MAX_WIDTH / this._natWidth : this._MAX_HEIGHT / this._natHeight;

        if (imgRatio > UploadModule.ASPECT_RATIO) {
            var width = this._natHeight * UploadModule.ASPECT_RATIO;
            sel.x = (this._natWidth - width) / 2;
            sel.x2 = sel.x + width;
            sel.y = 0;
            sel.y2 = this._natHeight;
        } else {
            var height = this._natWidth / UploadModule.ASPECT_RATIO;
            sel.x = 0;
            sel.x2 = this._natWidth;
            sel.y = (this._natHeight - height) / 2;
            sel.y2 = sel.y + height;
        }

        this._cropImg.Jcrop({
            boxWidth: this._MAX_WIDTH, // bouding box ffor the image
            boxHeight: this._MAX_HEIGHT,
            onChange: bindContext(this, this._updatePreview), // callback method
            onSelect: bindContext(this, this._updatePreview),
            setSelect: [sel.x * zoom, sel.y * zoom, sel.x2 * zoom, sel.y2 * zoom], // initial selection
            aspectRatio: UploadModule.ASPECT_RATIO
        });
    };

    this._updatePreview = function(coords)
    {
        if (!coords.w || !coords.h) return;
        this._cropCoord = coords;

        var rx = this._previewWidth / coords.w;
        var ry = this._previewHeight / coords.h;

        this._previewPic.css({
            width: Math.round(rx * this._natWidth) + 'px',
            height: Math.round(ry * this._natHeight) + 'px',
            marginLeft: '-' + Math.round(rx * coords.x) + 'px',
            marginTop: '-' + Math.round(ry * coords.y) + 'px'
        });
    };

    this._submitCrop = function()
    {
        $.ajax({
           url: "/dynamic/photo/scratch/crop",
           type: 'GET',
           data : { x : this._cropCoord.x, y : this._cropCoord.y,
               width : this._cropCoord.w, height : this._cropCoord.h },
           dataType: 'text',
           success: bindContext(this, this._handleCrop)
       });
    };

    this._handleCrop = function() {
        if (this._callback) this._callback();
        this._displayDialog(null);
    };

    
}


UploadModule.ASPECT_RATIO = 116 / 150;

UploadModule.NAME ="UploadModule";

UploadModule.prototype = new Module();