include('Ajax');
include('XMLProcessor');

var API_Client = function (url) {
    var self = this;

    this.url = url;
    this.default_error_handler = null;

    this.create_request = function (method) {
        var Request = new Ajax;
        Request.url = self.url;
        Request.charset = 'UTF-8';
        Request.method = method;
        Request.error_handler = function () {self.receive_error(Request)};
        return Request;
    }

    this.parse_xml_response = function (xml_response) {
        var response = {};
        if (xml_response) {
            var root = xml_response.getElementsByTagName('response');
            if (root[0]) {
                response.status = root[0].getAttribute('status');
                var message = root[0].getElementsByTagName('message');
                if (message[0]) {
                    response.message = (message[0].firstChild || message[0]).nodeValue;
                }
            }
        }
        return response;
    }

    // error
    this.receive_error = function (Request, handler) {
        // parse response
        var response = self.parse_xml_response(Request);

        // call handler
        if (handler) {
            handler(response);
        } else {
            self.default_error_handler(response);
        }
    }

    // add
    this.send_add = function (data, response_handler, error_handler) {
        var Request = self.create_request('POST');
        Request.response_handler = function () {self.receive_add(Request, response_handler)};
        if (error_handler) {
            Request.error_handler = function () {self.receive_error(Request, error_handler)};
        }
        Request.send(data);
    }

    this.receive_add = function (Request, handler) {
        // parse response
        var response = {};
        if (Request.xml_response) {
            response = self.parse_xml_response(Request.xml_response);
            var root = XMLProcessor.get_root_element(Request.xml_response);
            var items = root.getElementsByTagName('item');
            if (items[0]) {
                response.item = XMLProcessor.get_node_data(items[0]);
                response.item.id = items[0].getAttribute('id');
                response.item.title = items[0].getAttribute('title');
                response.item.module = items[0].getAttribute('module');
            }
        } else {
            var response = {};
        }

        // call handler
        handler(response);
    }

    // edit
    this.send_edit = function (data, response_handler, error_handler) {
        var Request = self.create_request('PUT');
        Request.response_handler = function () {self.receive_edit(Request, response_handler)};
        if (error_handler) {
            Request.error_handler = function () {self.receive_error(Request, error_handler)};
        }
        Request.send(data);
    }

    this.receive_edit = function (Request, handler) {
        // parse response
        var response = {};
        if (Request.xml_response) {
            response = self.parse_xml_response(Request.xml_response);
            var root = XMLProcessor.get_root_element(Request.xml_response);
            var items = root.getElementsByTagName('item');
            if (items[0]) {
                response.item = XMLProcessor.get_node_data(items[0]);
                response.item.id = items[0].getAttribute('id');
                response.item.title = items[0].getAttribute('title');
                response.item.module = items[0].getAttribute('module');
            }
        }

        // call handler
        handler(response);
    }

    // delete
    this.send_delete = function (id, response_handler, error_handler) {
        // analyze id
        var data = null;
        if (typeof id == 'array') {
            data = {id: id}; // :-)
        } else {
            data = {id: id};
        }

        var Request = self.create_request('DELETE');
        Request.response_handler = function () {self.receive_delete(Request, response_handler)};
        if (error_handler) {
            Request.error_handler = function () {self.receive_error(Request, error_handler)};
        }
        Request.send(data);
    }

    this.receive_delete = function (Request, handler) {
        // parse response
        var response = {};
        if (Request.xml_response) {
            response = this.parse_xml_response(Request.xml_response);
            var root = XMLProcessor.get_root_element(Request.xml_response);
            response.items = [];
            for (var i = 0; i < root.childNodes.length; i ++) {
                if (root.childNodes[i].tagName == 'item') {
                    var item = {id: root.childNodes[i].getAttribute('id')};
                    response.items.push(item);
                }
            }
        }

        // call handler
        handler(response);
    }

    // view - todo
    this.send_view = function (id, response_handler, error_handler) {
        var Request = self.create_request('GET');
        Request.response_handler = function () {self.receive_view(Request, response_handler)};
        if (error_handler) {
            Request.error_handler = function () {self.receive_view(Request, error_handler)};
        }
        Request.send({id: id, full: true});
    }

    this.receive_view = function (Request, handler) {
        // parse response
        var response = {};
        if (Request.xml_response) {
            response = this.parse_xml_response(Request.xml_response);
            var root = XMLProcessor.get_root_element(Request.xml_response);
            var items = root.getElementsByTagName('item');
            if (items[0]) {
                response.item = XMLProcessor.get_node_data(items[0]);
                response.item.id = items[0].getAttribute('id');
                response.item.module = items[0].getAttribute('module');
            }
            var permissions = root.getElementsByTagName('permissions');
            response.permissions = {};
            for (var i = 0; i < permissions.length; i ++) {
                response.permissions[permissions[i].getAttribute('group')] = {
                    select: permissions[i].getAttribute('select') == 1 ? true : false,
                    view:   permissions[i].getAttribute('view') == 1 ? true : false,
                    modify: permissions[i].getAttribute('modify') == 1 ? true : false,
                    use:    permissions[i].getAttribute('use') == 1 ? true : false,
                    admin:  permissions[i].getAttribute('admin') == 1 ? true : false
                };
            }
        }

        // call handler
        handler(response);
    }

    // list
    this.send_list = function (data, response_handler, error_handler) {
        var Request = self.create_request('GET');
        Request.response_handler = function () {self.receive_list(Request, response_handler)};
        if (error_handler) {
            Request.error_handler = function () {self.receive_error(Request, error_handler)};
        }
        Request.send(data);
    }

    this.receive_list = function (Request, handler) {
        var response = {};
        if (Request.xml_response) {
            response = this.parse_xml_response(Request.xml_response);
            var root = XMLProcessor.get_root_element(Request.xml_response);
            response.items = [];
            for (var i = 0; i < root.childNodes.length; i ++) {
                if (root.childNodes[i].tagName == 'item') {
                    var item = XMLProcessor.get_node_data(root.childNodes[i]);
                    item.id = root.childNodes[i].getAttribute('id');
                    item.module = root.childNodes[i].getAttribute('module');
                    item.title = root.childNodes[i].getAttribute('title');
                    item.permissions = {
                        select: item.select == 1 ? true : false,
                        view:   item.view == 1 ? true : false,
                        modify: item.modify == 1 ? true : false,
                        use:    item.use == 1 ? true : false,
                        admin:  item.admin == 1 ? true : false
                    };
                    response.items.push(item);
                }
            }
        }

        handler(response);
    }

    // tree
    this.send_tree = function (parameters, response_handler, error_handler) {
        var Request = self.create_request('GET');
        Request.response_handler = function () {self.receive_tree(Request, response_handler)};
        if (error_handler) {
            Request.error_handler = function () {self.receive_error(Request, error_handler)};
        }
        Request.send({tree: true});
    }

    this.receive_tree = function (Request, handler) {
        var response = {};
        if (Request.xml_response) {
            var root = XMLProcessor.get_root_element(Request.xml_response);
            var items = Request.xml_response.getElementsByTagName('item');
            response.tree = XMLProcessor.get_tree_data(items);
        }

        handler(response);
    }

}
