
var Thrift = require('../nodejs/thrift-node');

// Define types and services
var Rpc = {};

Rpc.NodeWebkitService = {};

Rpc.NodeWebkitService.markup = Thrift.Method.define({
    alias: 'markup',
    args: Thrift.Struct.define('markupArgs', {
        1: { alias: 'resourceUrl', type: Thrift.Type.STRING, index: 0 },
        7: { alias: 'title', type: Thrift.Type.STRING, index: 1 },
        2: { alias: 'x', type: Thrift.Type.I32, index: 2 },
        3: { alias: 'y', type: Thrift.Type.I32, index: 3 },
        4: { alias: 'width', type: Thrift.Type.I32, index: 4 },
        5: { alias: 'height', type: Thrift.Type.I32, index: 5 },
        6: { alias: 'trigger', type: Thrift.Type.I32, index: 6 }
    }),
    result: Thrift.Struct.define('markupResult')
});

Rpc.NodeWebkitService.markupPdf = Thrift.Method.define({
    alias: 'markupPdf',
    args: Thrift.Struct.define('markupPdfArgs', {
        1: { alias: 'pdfUrl', type: Thrift.Type.STRING, index: 0 },
        2: { alias: 'manifestUrl', type: Thrift.Type.STRING, index: 1 },
        3: { alias: 'pageNum', type: Thrift.Type.I32, index: 2 },
        9: { alias: 'title', type: Thrift.Type.STRING, index: 3 },
        4: { alias: 'x', type: Thrift.Type.I32, index: 4 },
        5: { alias: 'y', type: Thrift.Type.I32, index: 5 },
        6: { alias: 'width', type: Thrift.Type.I32, index: 6 },
        7: { alias: 'height', type: Thrift.Type.I32, index: 7 },
        8: { alias: 'trigger', type: Thrift.Type.I32, index: 8 }
    }),
    result: Thrift.Struct.define('markupPdfResult')
});

Rpc.NodeWebkitService.focusMarkupWindow = Thrift.Method.define({
    alias: 'focusMarkupWindow',
    args: Thrift.Struct.define('focusMarkupWindowArgs'),
    result: Thrift.Struct.define('focusMarkupWindowResult')
});

Rpc.NodeWebkitService.closeMarkupWindow = Thrift.Method.define({
    alias: 'closeMarkupWindow',
    args: Thrift.Struct.define('closeMarkupWindowArgs'),
    result: Thrift.Struct.define('closeMarkupWindowResult')
});

Rpc.NodeWebkitService.closeMarkupWindowWithMessage = Thrift.Method.define({
    alias: 'closeMarkupWindowWithMessage',
    args: Thrift.Struct.define('closeMarkupWindowWithMessageArgs', {
        1: { alias: 'message', type: Thrift.Type.STRING }
    }),
    result: Thrift.Struct.define('closeMarkupWindowWithMessageResult')
});

Rpc.NodeWebkitService.rotateImage = Thrift.Method.define({
    alias: 'rotateImage',
    args: Thrift.Struct.define('rotateImageArgs', {
        1: { alias: 'resourceUrl', type: Thrift.Type.STRING },
        2: { alias: 'theta', type: Thrift.Type.I32 }
    }),
    result: Thrift.Struct.define('rotateImageResult')
});

Rpc.NodeWebkitService.resizeImage = Thrift.Method.define({
    alias: 'resizeImage',
    args: Thrift.Struct.define('resizeImageArgs', {
        1: { alias: 'resourceUrl', type: Thrift.Type.STRING },
        2: { alias: 'width', type: Thrift.Type.I32 },
        3: { alias: 'height', type: Thrift.Type.I32 }
    }),
    result: Thrift.Struct.define('resizeImageResult')
});

Rpc.NodeWebkitService.clearImage = Thrift.Method.define({
    alias: 'clearImage',
    args: Thrift.Struct.define('clearImageArgs', {
        1: { alias: 'resourceUrl', type: Thrift.Type.STRING }
    }),
    result: Thrift.Struct.define('clearImageResult')
});

Rpc.NodeWebkitService.present = Thrift.Method.define({
    alias: 'present',
    args: Thrift.Struct.define('presentArgs', {
        1: { alias: 'noteIds', type: Thrift.Type.LIST, def: Thrift.List.define(Thrift.Type.I32) },
        2: { alias: 'index', type: Thrift.Type.I32 },
        3: { alias: 'x', type: Thrift.Type.I32 },
        4: { alias: 'y', type: Thrift.Type.I32 },
        5: { alias: 'width', type: Thrift.Type.I32 },
        6: { alias: 'height', type: Thrift.Type.I32 },
        7: { alias: 'trigger', type: Thrift.Type.I32 }
    }),
    result: Thrift.Struct.define('presentResult')
});

Rpc.NodeWebkitService.focusPresentationWindow = Thrift.Method.define({
    alias: 'focusPresentationWindow',
    args: Thrift.Struct.define('focusPresentationWindowArgs'),
    result: Thrift.Struct.define('focusPresentationWindowResult')
});

Rpc.NodeWebkitService.closePresentationWindow = Thrift.Method.define({
    alias: 'closePresentationWindow',
    args: Thrift.Struct.define('closePresentationWindowArgs'),
    result: Thrift.Struct.define('closePresentationWindowResult')
});

Rpc.NodeWebkitService.minimizeWindow = Thrift.Method.define({
    alias: 'minimizeWindow',
    args: Thrift.Struct.define('minimizeWindowArgs'),
    result: Thrift.Struct.define('minimizeWindowResult')
});

Rpc.NodeWebkitService.restoreWindow = Thrift.Method.define({
    alias: 'restoreWindow',
    args: Thrift.Struct.define('restoreWindowArgs'),
    result: Thrift.Struct.define('restoreWindowResult')
});

Rpc.NodeWebkitService.quit = Thrift.Method.define({
    alias: 'quit',
    args: Thrift.Struct.define('quitArgs'),
    result: Thrift.Struct.define('quitResult')
});


// Define NodeWebkitService Client
(function (namespace) {
    var ServiceDef = namespace.NodeWebkitService;

    function Client(output) {
        this.output = output;
        this.seqid = 0;
    }

    Client.prototype.markup = function (resourceUrl, x, y, width, height, trigger, onsuccess, onerror) {
        var mdef = ServiceDef.markup;
        var args = new mdef.args();
        args.resourceUrl = resourceUrl;
        args.x = x;
        args.y = y;
        args.width = width;
        args.height = height;
        args.trigger = trigger;
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.markupPdf = function (pdfUrl, manifestUrl, x, y, width, height, trigger, onsuccess, onerror) {
        var mdef = ServiceDef.markupPdf;
        var args = new mdef.args();
        args.pdfUrl = pdfUrl;
        args.manifestUrl = manifestUrl;
        args.x = x;
        args.y = y;
        args.width = width;
        args.height = height;
        args.trigger = trigger;
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.focusMarkupWindow = function (resourceUrl, onsuccess, onerror) {
        var mdef = ServiceDef.focusMarkupWindow;
        var args = new mdef.args();
        args.resourceUrl = resourceUrl;
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.closeMarkupWindow = function (resourceUrl, onsuccess, onerror) {
        var mdef = ServiceDef.closeMarkupWindow;
        var args = new mdef.args();
        args.resourceUrl = resourceUrl;
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.rotateImage = function (resourceUrl, theta, onsuccess, onerror) {
        var mdef = ServiceDef.rotateImage;
        var args = new mdef.args();
        args.resourceUrl = resourceUrl;
        args.theta = theta;
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.resizeImage = function (resourceUrl, width, height, onsuccess, onerror) {
        var mdef = ServiceDef.resizeImage;
        var args = new mdef.args();
        args.resourceUrl = resourceUrl;
        args.width = width;
        args.height = height;
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.clearImage = function (resourceUrl, onsuccess, onerror) {
        var mdef = ServiceDef.clearImage;
        var args = new mdef.args();
        args.resourceUrl = resourceUrl;
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.present = function (noteIds, index, x, y, width, height, trigger, onsuccess, onerror) {
        var mdef = ServiceDef.present;
        var args = new mdef.args();
        args.noteIds = noteIds;
        args.index = index;
        args.x = x;
        args.y = y;
        args.width = width;
        args.height = height;
        args.trigger = trigger;
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.focusPresentationWindow = function (onsuccess, onerror) {
        var mdef = ServiceDef.focusPresentationWindow;
        var args = new mdef.args();
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.closePresentationWindow = function (onsuccess, onerror) {
        var mdef = ServiceDef.closePresentationWindow;
        var args = new mdef.args();
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.minimizeWindow = function (onsuccess, onerror) {
        var mdef = ServiceDef.minimizeWindow;
        var args = new mdef.args();
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.restoreWindow = function (onsuccess, onerror) {
        var mdef = ServiceDef.restoreWindow;
        var args = new mdef.args();
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    Client.prototype.quit = function (onsuccess, onerror) {
        var mdef = ServiceDef.quit;
        var args = new mdef.args();
        mdef.sendRequest(this.output, this.seqid++, args, onsuccess, onerror);
    };

    ServiceDef.Client = Client;
})(Rpc);

// Define NodeWebkitService Server
(function (namespace) {
    var ServiceDef = namespace.NodeWebkitService;

    function Server(service, stransport, Protocol, async) {
        var methodName;

        async = (async == null) ? true : async;
        this.service = service;
        this.stransport = stransport;
        this.processor = new Thrift.Processor();

        for (methodName in ServiceDef) {
            if (service[methodName]) {
                this.processor.addMethod(ServiceDef[methodName], service[methodName].bind(service), async);
            }
        }

        this.stransport.process = function (input, output, noop) {
            var inprot = new Protocol(input);
            var outprot = new Protocol(output);
            this.processor.process(inprot, outprot, noop);
        }.bind(this);
    }

    Server.prototype.start = function () {
        this.stransport.listen();
    };

    Server.prototype.stop = function () {
        this.stransport.close();
    };

    ServiceDef.Server = Server;
})(Rpc);

// Node exports
Object.keys(Rpc).forEach(function (key) {
    exports[key] = Rpc[key];
});
