1 /*
  2  * NumPlan.js - Represent a phone numbering plan.
  3  *
  4  * Copyright © 2014-2015, 2018, JEDLSoft
  5  *
  6  * Licensed under the Apache License, Version 2.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at
  9  *
 10  *     http://www.apache.org/licenses/LICENSE-2.0
 11  *
 12  * Unless required by applicable law or agreed to in writing, software
 13  * distributed under the License is distributed on an "AS IS" BASIS,
 14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  *
 16  * See the License for the specific language governing permissions and
 17  * limitations under the License.
 18  */
 19 
 20 // !data numplan
 21 
 22 var ilib = require("./ilib.js");
 23 var Utils = require("./Utils.js");
 24 var Locale = require("./Locale.js");
 25 
 26 /**
 27  * @class
 28  * Create a numbering plan information instance for a particular country's plan.<p>
 29  *
 30  * The options may contain any of the following properties:
 31  *
 32  * <ul>
 33  * <li><i>locale</i> - locale for which the numbering plan is sought. This locale
 34  * will be mapped to the actual numbering plan, which may be shared amongst a
 35  * number of countries.
 36  *
 37  * <li>onLoad - a callback function to call when the date format object is fully
 38  * loaded. When the onLoad option is given, the DateFmt object will attempt to
 39  * load any missing locale data using the ilib loader callback.
 40  * When the constructor is done (even if the data is already preassembled), the
 41  * onLoad function is called with the current instance as a parameter, so this
 42  * callback can be used with preassembled or dynamic loading or a mix of the two.
 43  *
 44  * <li>sync - tell whether to load any missing locale data synchronously or
 45  * asynchronously. If this option is given as "false", then the "onLoad"
 46  * callback must be given, as the instance returned from this constructor will
 47  * not be usable for a while.
 48  *
 49  * <li><i>loadParams</i> - an object containing parameters to pass to the
 50  * loader callback function when locale data is missing. The parameters are not
 51  * interpretted or modified in any way. They are simply passed along. The object
 52  * may contain any property/value pairs as long as the calling code is in
 53  * agreement with the loader callback function as to what those parameters mean.
 54  * </ul>
 55  *
 56  * @private
 57  * @constructor
 58  * @param {Object} options options governing the way this plan is loaded
 59  */
 60 var NumberingPlan = function (options) {
 61     var sync = true,
 62         loadParams = {};
 63 
 64     this.locale = new Locale();
 65 
 66     if (options) {
 67         if (options.locale) {
 68             this.locale = (typeof(options.locale) === 'string') ? new Locale(options.locale) : options.locale;
 69         }
 70 
 71         if (typeof(options.sync) !== 'undefined') {
 72             sync = !!options.sync;
 73         }
 74 
 75         if (options.loadParams) {
 76             loadParams = options.loadParams;
 77         }
 78     }
 79 
 80     Utils.loadData({
 81         name: "numplan.json",
 82         object: "NumberingPlan",
 83         locale: this.locale,
 84         sync: sync,
 85         loadParams: loadParams,
 86         callback: ilib.bind(this, function (npdata) {
 87             if (!npdata) {
 88                 npdata = {
 89                     "region": "XX",
 90                     "skipTrunk": false,
 91                     "trunkCode": "0",
 92                     "iddCode": "00",
 93                     "dialingPlan": "closed",
 94                     "commonFormatChars": " ()-./",
 95                     "fieldLengths": {
 96                         "areaCode": 0,
 97                         "cic": 0,
 98                         "mobilePrefix": 0,
 99                         "serviceCode": 0
100                     }
101                 };
102             }
103 
104             /**
105              * @type {{
106              *   region:string,
107              *   skipTrunk:boolean,
108              *   trunkCode:string,
109              *   iddCode:string,
110              *   dialingPlan:string,
111              *   commonFormatChars:string,
112              *   fieldLengths:Object.<string,number>,
113              *   contextFree:boolean,
114              *   findExtensions:boolean,
115              *   trunkRequired:boolean,
116              *   extendedAreaCodes:boolean
117              * }}
118              */
119             this.npdata = npdata;
120             if (options && typeof(options.onLoad) === 'function') {
121                 options.onLoad(this);
122             }
123         })
124     });
125 };
126 
127 NumberingPlan.prototype = {
128     /**
129      * Return the name of this plan. This may be different than the
130      * name of the region because sometimes multiple countries share
131      * the same plan.
132      * @return {string} the name of the plan
133      */
134     getName: function() {
135         return this.npdata.region;
136     },
137 
138     /**
139      * Return the trunk code of the current plan as a string.
140      * @return {string|undefined} the trunk code of the plan or
141      * undefined if there is no trunk code in this plan
142      */
143     getTrunkCode: function() {
144         return this.npdata.trunkCode;
145     },
146 
147     /**
148      * Return the international direct dialing code of this plan.
149      * @return {string} the IDD code of this plan
150      */
151     getIDDCode: function() {
152         return this.npdata.iddCode;
153     },
154 
155     /**
156      * Return the plan style for this plan. The plan style may be
157      * one of:
158      *
159      * <ul>
160      * <li>"open" - area codes may be left off if the caller is
161      * dialing to another number within the same area code
162      * <li>"closed" - the area code must always be specified, even
163      * if calling another number within the same area code
164      * </ul>
165      *
166      * @return {string} the plan style, "open" or "closed"
167      */
168     getPlanStyle: function() {
169         return this.npdata.dialingPlan;
170     },
171     /** [Need Comment]
172      * Return a contextFree
173      *
174      * @return {boolean}
175      */
176     getContextFree: function() {
177         return this.npdata.contextFree;
178     },
179     /** [Need Comment]
180      * Return a findExtensions
181      *
182      * @return {boolean}
183      */
184     getFindExtensions: function() {
185         return this.npdata.findExtensions;
186     },
187     /** [Need Comment]
188      * Return a skipTrunk
189      *
190      * @return {boolean}
191      */
192     getSkipTrunk: function() {
193         return this.npdata.skipTrunk;
194     },
195     /** [Need Comment]
196      * Return a skipTrunk
197      *
198      * @return {boolean}
199      */
200     getTrunkRequired: function() {
201         return this.npdata.trunkRequired;
202     },
203     /**
204      * Return true if this plan uses extended area codes.
205      * @return {boolean} true if the plan uses extended area codes
206      */
207     getExtendedAreaCode: function() {
208         return this.npdata.extendedAreaCodes;
209     },
210     /**
211      * Return a string containing all of the common format characters
212      * used to format numbers.
213      * @return {string} the common format characters fused in this locale
214      */
215     getCommonFormatChars: function() {
216         return this.npdata.commonFormatChars;
217     },
218 
219     /**
220      * Return the length of the field with the given name. If the length
221      * is returned as 0, this means it is variable length.
222      *
223      * @param {string} field name of the field for which the length is
224      * being sought
225      * @return {number} if positive, this gives the length of the given
226      * field. If zero, the field is variable length. If negative, the
227      * field is not known.
228      */
229     getFieldLength: function (field) {
230         var dataField = this.npdata.fieldLengths;
231 
232         return dataField[field];
233     }
234 };
235 
236 module.exports = NumberingPlan;
237