/*jshint -W069 */
/*global angular:false */
angular.module('{{&moduleName}}', [])
.factory('{{&className}}', ['$q', '$http', '$rootScope', function($q, $http, $rootScope){
    'use strict';

    /**
     * {{&description}}
     * @class {{&className}}
     * @param {(string|object)} [domainOrOptions] - The project domain or options object. If object, see the object's optional properties.
     * @param {string} [domainOrOptions.domain] - The project domain
     * @param {string} [domainOrOptions.cache] - An angularjs cache implementation
     * @param {object} [domainOrOptions.token] - auth token - object with value property and optional headerOrQueryName and isQuery properties
     * @param {string} [cache] - An angularjs cache implementation
     */
    var {{&className}} = (function(){
        function {{&className}}(options, cache){
            var domain = (typeof options === 'object') ? options.domain : options;
            this.domain = typeof(domain) === 'string' ? domain : '{{&domain}}';
            cache = cache || ((typeof options === 'object') ? options.cache : cache);
            this.cache = cache;
            {{#isSecure}}
                this.token = (typeof options === 'object') ? (options.token ? options.token : {}) : {};
            {{/isSecure}}
        }

        {{&className}}.prototype.$on = function($scope, path, handler){
            var url = domain + path;
            $scope.$on(url, function(){
                handler();
            });
            return this;
        };

        {{&className}}.prototype.$broadcast = function(path){
            var url = domain + path;
            //cache.remove(url);
            $rootScope.$broadcast(url);
            return this;
        };

        {{&className}}.transformRequest = function(obj) {
            var str = [];
            for(var p in obj) {
                var val = obj[p];
                if(angular.isArray(val)) {
                   val.forEach(function(val){
                     str.push(encodeURIComponent(p) + "=" + encodeURIComponent(val));
                   });
                } else {
                   str.push(encodeURIComponent(p) + "=" + encodeURIComponent(val));
                }
            }
            return str.join("&");
        };

        {{#isSecure}}
            /**
             * Set Token
             * @method
             * @name {{&className}}#setToken
             * @param {string} value - token's value
             * @param {string} headerOrQueryName - the header or query name to send the token at
             * @param {boolean} isQuery - true if send the token as query param, otherwise, send as header param
             *
             */
            {{&className}}.prototype.setToken = function (value, headerOrQueryName, isQuery) {
                this.token.value = value;
                this.token.headerOrQueryName = headerOrQueryName;
                this.token.isQuery = isQuery;
            };
        {{/isSecure}}

        {{#methods}}
            {{> method}}
        {{/methods}}

  return {{&className}};
    })();

    return {{&className}};
}]);
