/*
   Copyright 2010 Hanov Solutions Inc. All Rights Reserved

   steve.hanov@gmail.com
 */

/*jslint evil: true */

/** @constructor */
function Overlay()
{

}

Overlay.prototype.hide = function() 
{
    this.div.remove();
};

Overlay.prototype.show = function( clickfn )
{
    this.div = $("<div>");
    var body = $(window);
    this.div.css("position", "fixed");
    this.div.css("background", "black");
    this.div.css("opacity","0.25");
    this.div.css("left", "0");
    this.div.css("top", "0");
    this.div.css("zindex", "1");
    this.div.css("width", ""+body.width() + "px");
    this.div.css("height", ""+body.height() + "px");
    this.div.css("display", "none");
    this.div.click( function() {
        clickfn();
    });
    $("body").append( this.div );
    $(this.div).fadeIn("normal");
};

/** @constructor */
function CreateAccountDialog()
{
    this.setErrorText("");
    this.form = document.getElementById("createaccountform");
}

CreateAccountDialog.prototype = {
    divId: "createaccount",

    onsubmit: function()
    {
        if ( this.form["userNameInput"].value === "" ) {
            this.setErrorText("Username is blank.");
        } else if ( this.form["passwordInput1"].value === "" ) {
            this.setErrorText("Password is blank.");
        } else if ( this.form["passwordInput2"].value !== this.form["passwordInput1"].value ) {
            this.setErrorText("Passwords do not match.");
        } else {
            this.form["submitButton"].disabled = true;
            this.form["cancelButton"].disabled = true;
            var self = this;
            session.createUser( this.form["userNameInput"].value,
                this.form["passwordInput1"].value, 
                function(status, mapping) {
                    if ( status === "ok" ) {
                        page.hideDialog();
                        page.onLoggedIn(mapping);
                    } else {
                        self.form["submitButton"].disabled = false;
                        self.form["cancelButton"].disabled = false;
                        self.setErrorText(status);
                    }
                });
        }
        return false;
    },

    setErrorText: function(str)
    {
        $("#createaccounterror").text(str);
    }

};

CreateAccountDialog.prototype["onsubmit"] = CreateAccountDialog.prototype.onsubmit;

/** @constructor */
function ChangePasswordDialog()
{
    this.setErrorText("");
    this.form = document.getElementById("changepasswordform");
    this.form["oldpassword"].value = "";
    this.form["newpassword1"].value = "";
    this.form["newpassword2"].value = "";
    this.form["submitButton"].disabled = false;
    this.form["cancelButton"].disabled = false;
}

ChangePasswordDialog.prototype = {
    divId: "changePasswordDiv",

    onsubmit: function()
    {
        var oldPassword = this.form["oldpassword"].value;
        var newPassword1 = this.form["newpassword1"].value;
        var newPassword2 = this.form["newpassword2"].value;
        if ( newPassword1 !== newPassword2 ) {
            this.setErrorText("Passwords do not match.");
        } else if ( newPassword1 === "" ) {
            this.setErrorText("Password is blank.");
        } else {
            this.setErrorText("");
            this.form["submitButton"].disabled = true;
            this.form["cancelButton"].disabled = true;
            var self = this;
            session.changePassword( oldPassword, newPassword1,
                function(status) {
                    if ( status === "ok" ) {
                        page.hideDialog();
                    } else {
                        self.form["submitButton"].disabled = false;
                        self.form["cancelButton"].disabled = false;
                        self.setErrorText(status);
                    }
                });
        }
        return false;
    },

    setErrorText: function(str)
    {
        $("#passwordError").text(str);
    }

};

ChangePasswordDialog.prototype["onsubmit"] = ChangePasswordDialog.prototype.onsubmit;

/** @constructor */
function CheckSaveDialog(fn)
{
    this.fn = fn;
    $("#surediv").slideDown("normal");
}

CheckSaveDialog.prototype = {
    divId: "checksave",

    okayClicked: function() 
    {
        page.hideDialog();
        if ( this.fn ) {
            this.fn();
        }
    },

    cancelClicked: function()
    {
        page.hideDialog(); 
    }

};

/** @constructor */
function MessageDialog(args)
{
    $("#message-title").text(args.title);
    $("#message-text").text(args.text);
}

MessageDialog.prototype = {
    divId: "message",

    okayClicked: function() 
    {
        page.hideDialog();
    }
};

MessageDialog.prototype["okayClicked"] = MessageDialog.prototype.okayClicked;

/** @constructor */
function ShareDialog(fn)
{
    var self = this;
    $("#share-enabled").hide();
    $("#share-working").hide();
    $("#share-not-enabled").hide();
    if ( !gDrawApp.file.shared ) {
        $("#share-not-enabled").show();
    } else {
        this.showShared();
    }
}

ShareDialog.prototype = {
    divId: "share",

    unshareClicked: function() 
    {
        var self = this;
        $("#share-enabled").hide();
        $("#share-working").show();

        gDrawApp.file.shared = 0;
        gDrawApp.file.data = '';
        session.updateFile( gDrawApp.file,
                function( status ) {

            $("#share-working").hide();
            if ( status === "ok" ) {
                gDrawApp.shared = false;
                page.hideDialog();
            } else {
                gDrawApp.file.shared = 1;
                self.error( status );
            }
        });
    },

    shareClicked: function() 
    {
        var self = this;
        $("#share-not-enabled").hide();
        $("#share-working").show();

        gDrawApp.file.shared = 1;
        gDrawApp.file.data = '';
        session.updateFile( gDrawApp.file,
                function( status ) {

            $("#share-working").hide();
            if ( status === "ok" ) {
                self.showShared();
            } else {
                gDrawApp.shared = 0;
                self.error( status );
            }
        });
    },

    showShared: function()
    {
        var base = "http://zwibbler.com/shared/" + gDrawApp.file.id + ".";
        var png = base + "png";
        var pdf = base + "pdf";
        var svg = base + "svg";

        $("#share-png")[0].value = png;
        $("#share-pdf")[0].value = pdf;
        $("#share-svg")[0].value = svg;

        $("#share-enabled").show();
    },

    error: function(status)
    {
        $("#share-error").show();
        $("#share-error-code").text(status);
    }
};

ShareDialog.prototype["shareClicked"] = ShareDialog.prototype.shareClicked;
ShareDialog.prototype["unshareClicked"] = ShareDialog.prototype.unshareClicked;

$("#savefilename").keydown( function( e ) {
    if ( e.keyCode === 13 ) {
        page.currentDialog().okayClicked();
    }
});

/** @constructor */
function SaveDialog(fn)
{
    var input = document.getElementById("savefilename");
    input.value = gDrawApp.file.name;
    $("#save-normal").show();
    if ( session.username ) {
        $("#no-account-warning").hide();
    } else {
        $("#no-account-warning").show();
    }
    $("#save-working").hide();
    $("#save-error").hide();
    $("#savediv").slideDown("normal");
}

SaveDialog.prototype = {
    divId: "save",

    hide: function()
    {
        $("#savediv").slideUp("normal");
    },

    okayClicked: function() 
    {
        var input = document.getElementById("savefilename");
        var nameWasDifferent = gDrawApp.file.name !== input.value;
        gDrawApp.file.name = input.value;
        $("#save-normal").hide();
        $("#save-working").show();
        var text = json(gDrawApp.drawView.doc.root.save());

        var self = this;
        if ( gDrawApp.file.id === -1 || nameWasDifferent) {
            session.createFile( gDrawApp.file.name, text,
                function( status, id ) {
                    if ( status === "ok" ) {
                        gDrawApp.file.id = id;
                        gDrawApp.file.shared = 0;
                        page.hideDialog();
                        gDrawApp.undoStack.dirty = false;
                    } else {
                        self.error( status );
                    }
                });
        } else {
            gDrawApp.file.data = text;
            session.updateFile( gDrawApp.file,
                function( status )
                {
                    if ( status === "ok" ) {
                        page.hideDialog();
                        gDrawApp.undoStack.dirty = false;
                    } else {
                        self.error( status );
                    }
                });
        }
    },

    error: function(status)
    {
        $("#save-working").hide();
        $("#save-error").show();
        $("#save-error-code").text(status);
    },

    cancelClicked: function()
    {
        page.hideDialog(); 
    }
};

SaveDialog.prototype["okayClicked"] = SaveDialog.prototype.okayClicked;
SaveDialog.prototype["cancelClicked"] = SaveDialog.prototype.cancelClicked;

$("#previewcanvas").click( function() 
{
    if ( page.currentDialog().currentPreviewFile ) {
        page.currentDialog().okayClicked();
    }
});

/** @constructor */
function BrowseDialog(fn)
{
    var self = this;
    this.currentPreviewFile = null;
    if ( !this.initialized ) {
        this.initialized = true;
        this.clickOpenImg = document.createElement("img");
        this.clickOpenImg.src = "wd-clickopen.png";
    }

    self.mode = "normal";

    $("#deletebutton").hide();
    $("#browse-working").hide();
    $("#browse-prompt").hide();
    $("#browse-main").show();

    this.refreshFiles();
}

BrowseDialog.prototype = {
    divId: "browse",
    refreshFiles: function()
    {
        var self = this;
        var canvas = document.getElementById("previewcanvas");
        var ctx = canvas.getContext("2d");
        ctx.clearRect( 0, 0, 350, 350 );

        var filelist = $("#filelist");
        filelist.empty();
        var table = $("<table width='100%'>");

        function fileClicked() {
            $("#deletebutton").hide();
            session.readFile( this.myid, 
                function( status, file ) {
                    if ( status === "ok" ) {
                        self.previewFile( file );
                    }
                });
            return false;
        }

        for( var i = 0; i < session.files.length; i++ ) {
            var file = session.files[i];
            var bg = "#ffffff";
            if ( i & 1 ) {
                bg = "#C0C0C0";
            }

            var a = $("<a href=''>").text(file.name).click( fileClicked );
            a[0].myid = session.files[i].id;

            var d = new Date( parseInt( file["modificationDate"],10 ) * 1000 );
            d = d.toLocaleString();

            table.append( 
                $("<tr>").append( 
                    $("<td>").css("background", bg ).append(a) ).append(
                    $("<td>").css("background", bg ).text( d )
                    ));
        }

        filelist.append( table );
    },

    previewFile: function( file ) 
    {
        var obj;
        try {
            // V1 format does not include proper quoting. Therefore we need
            // to use eval.
            obj = Loader( eval("("+file.data+")" ) );
        } catch( e ) {
            alert(e);
            return;
        }
        this.currentPreviewFile = file;
        $("#deletebutton").show();
        var canvas = document.getElementById("previewcanvas");
        var ctx = canvas.getContext("2d");
        ctx.clearRect( 0, 0, 350, 350 );
        ctx.save();
        ctx.setTransform(0.5, 0, 0, 0.5, 0, 0 );
        try {
            obj.format(ctx);
            obj.draw( ctx );
        } catch( e2 ) {
        }
        ctx.setTransform(1, 0, 0, 1, 0, 0 );
        ctx.restore();
        if ( this.clickOpenImg.complete ) {
            ctx.drawImage( this.clickOpenImg, (350-170)/2, (350-66)/2 );
        }
    },

    deleteClicked: function() 
    {
        $("#browse-main").hide();
        $("#browse-prompt").show();
        this.mode = "prompt";
    },

    okayClicked: function() 
    {
        var self = this;
        if ( self.mode === "normal" ) {
            page.hideDialog();
            if ( this.currentPreviewFile ) {
                page.openFile( this.currentPreviewFile,
                    this.currentPreviewFile.data );
            }
        } else if ( self.mode === "prompt" ) {
            $("#browse-prompt").hide();
            $("#browse-working").show();

            session.deleteFile( this.currentPreviewFile.id, 
                function(status) {
                    $("#browse-working").hide();
                    $("#browse-main").show();
                    self.currentPreviewFile = null;
                    self.refreshFiles();
                    self.mode = "normal";
                });
        }
    },

    cancelClicked: function() 
    {
        if ( this.mode === "normal" ) {
            page.hideDialog();
        } else if ( this.mode === "prompt" ) {
            $("#browse-prompt").hide();
            $("#browse-main").show();
            this.mode = "normal";
        }
    }
};

BrowseDialog.prototype["okayClicked"] = BrowseDialog.prototype.okayClicked;
BrowseDialog.prototype["cancelClicked"] = BrowseDialog.prototype.cancelClicked;
BrowseDialog.prototype["deleteClicked"] = BrowseDialog.prototype.deleteClicked;

var Dialogs = {

    "createaccount": CreateAccountDialog,
    "checksave": CheckSaveDialog,
    "save": SaveDialog,
    "browse": BrowseDialog,
    "changepassword": ChangePasswordDialog,
    "message": MessageDialog,
    "share": ShareDialog
};


/** @constructor */
function Page()
{
    this.main = document.getElementById("main");
    this.dlg = null;
    this.overlay = new Overlay();

    this.dlg = null;
}

Page.prototype = {

    showDialog: function(name, param)
    {
        var self = this;
        this.hideDialog();
        this.overlay.show(
            function() {
                self.hideDialog();
            });
        this.dlg = new Dialogs[name](param);
        $("#"+this.dlg.divId).slideDown("normal");
    },

    hideDialog: function()
    {
        if ( this.dlg !== null ) {
            $("#"+this.dlg.divId).slideUp("normal");
            this.overlay.hide();
            this.dlg = null;
        }
    },

    currentDialog: function() 
    {
        return this.dlg;
    },

    login: function()
    {
        var form = document.getElementById("signInForm");
        var user = form["username"].value;
        var password = form["password"].value;
        form["signin"].disabled = true;

        var self = this;
        session.login( user, password, function( status, mapping ) 
            {
                form["signin"].disabled = false;
                if ( status === "ok" ) {
                    self.onLoggedIn(mapping);
                } else {
                    var div = document.getElementById("loginerror");
                    form["signin"].disabled = false;
                    $(div).empty();
                    $(div).text( status );
                }
            });
    },

    onLoggedIn: function(mapping)
    {
        var form = document.getElementById("signin");
        form.style.display = "none";
        var logoutDiv = document.getElementById("logout");
        logoutDiv.style.display = "block";

        if ( mapping && gDrawApp.file.id !== -1 &&
                gDrawApp.file.id in mapping ) {
            gDrawApp.file.id = mapping[gDrawApp.file.id];
        }
    },


    logout: function()
    {
        var self = this;
        var logoutDiv = document.getElementById("logout");
        logoutDiv.style.display = "none";
        session.logout( function( status ) 
            {
                if ( status === "ok" ) {
                    self.onLoggedOut();
                } else {
                    logoutDiv.style.display = "block";
                }
            });
    },

    onLoggedOut: function()
    {
        var form = document.getElementById("signin");
        form.style.display = "block";
        var logoutDiv = document.getElementById("logout");
        $(logoutDiv).hide();
        gDrawApp.file.id = -1;
        gDrawApp.file.shared = 0;
    },


    newDrawing: function()
    {
        this.checkSave( function()
        {
            gDrawApp.newDocument();
        });
    },

    checkSave: function( fn )
    {
        if ( gDrawApp.dirty() ) {
            this.showDialog( "checksave", fn );
        } else {
            fn();
        }
    },

    saveDrawing: function()
    {
        this.showDialog("save");
    },

    changePassword: function()
    {
        this.showDialog("changepassword");
    },

    browseDrawings: function()
    {
        var self = this;
        this.checkSave( function() {
            self.showDialog("browse");
        });
    },

    openFile: function( file, data ) 
    {
        LoadFile( eval("("+data+")"), file );
    },

    createAccount: function()
    {
        this.showDialog("createaccount");
    },

    onShare: function()
    {
        if ( !session.isLoggedIn() || gDrawApp.dirty() || gDrawApp.file.id === -1 ) {
            var title = "Log in first";
            if ( session.isLoggedIn() ) {
                title = "Save first";
            }
            this.showDialog("message", {
                title: title,
                text: "You can only share drawings if you log in and save them first."
            });
        } else {
            this.showDialog("share");
        }
    }
};
window["Page"] = Page;
Page.prototype["newDrawing"] = Page.prototype.newDrawing;
Page.prototype["browseDrawings"] = Page.prototype.browseDrawings;
Page.prototype["saveDrawing"] = Page.prototype.saveDrawing;
Page.prototype["logout"] = Page.prototype.logout;
Page.prototype["saveDrawing"] = Page.prototype.saveDrawing;
Page.prototype["createAccount"] = Page.prototype.createAccount;
Page.prototype["login"] = Page.prototype.login;
Page.prototype["currentDialog"] = Page.prototype.currentDialog;
Page.prototype["hideDialog"] = Page.prototype.hideDialog;
Page.prototype["changePassword"] = Page.prototype.changePassword;

