4c51c9ae25cfafda6519867789037fb3ddfd7485
[pdfium.git] / fpdfsdk / src / javascript / PublicMethods.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4  
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../include/javascript/JavaScript.h"
8 #include "../../include/javascript/IJavaScript.h"
9 #include "../../include/javascript/JS_Define.h"
10 #include "../../include/javascript/JS_Object.h"
11 #include "../../include/javascript/JS_Value.h"
12 #include "../../include/javascript/PublicMethods.h"
13 #include "../../include/javascript/JS_EventHandler.h"
14 #include "../../include/javascript/resource.h"
15 #include "../../include/javascript/JS_Context.h"
16 #include "../../include/javascript/JS_Value.h"
17 #include "../../include/javascript/util.h"
18 #include "../../include/javascript/Field.h"
19 #include "../../include/javascript/color.h"
20 #include "../../include/javascript/JS_Runtime.h"
21
22 static v8::Isolate* GetIsolate(IFXJS_Context* cc)
23 {
24         CJS_Context* pContext = (CJS_Context *)cc;
25         ASSERT(pContext != NULL);
26
27         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
28         ASSERT(pRuntime != NULL);
29
30         return pRuntime->GetIsolate();
31 }
32
33
34 /* -------------------------------- CJS_PublicMethods -------------------------------- */
35
36 #define DOUBLE_CORRECT  0.000000000000001
37
38 BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
39         JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format,6)
40         JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke,6)
41         JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format,2)
42         JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke,2)
43         JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx,1)
44         JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx,1)
45         JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format,1)
46         JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke,1)
47         JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx,1)
48         JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx,1)
49         JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format,1)
50         JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke,1)
51         JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format,1)
52         JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke,1)
53         JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx,1)
54         JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple,3)
55         JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber,1)
56         JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate,2)
57         JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate,4)
58         JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange,1)
59         JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx,2)
60         JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums,1)
61 END_JS_STATIC_GLOBAL_FUN()
62
63 IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
64
65 struct stru_TbConvert
66 {
67         FX_LPCSTR lpszJSMark;
68         FX_LPCSTR lpszCppMark;
69 };
70
71 static const stru_TbConvert fcTable[] = {
72         { "mmmm","%B" },
73         { "mmm", "%b" },
74         { "mm",  "%m" },
75         //"m"
76         { "dddd","%A" },
77         { "ddd", "%a" },
78         { "dd",  "%d" },
79         //"d",   "%w",
80         { "yyyy","%Y" },
81         { "yy",  "%y" },
82         { "HH",  "%H" },
83         //"H"
84         { "hh",  "%I" },
85         //"h"
86         { "MM",  "%M" },
87         //"M"
88         { "ss",  "%S" },
89         //"s
90         { "tt",  "%p" },
91         //"t"
92 };
93
94 static FX_LPCWSTR months[] =
95 {
96         L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec"
97 };
98
99 static FX_LPCWSTR fullmonths[] = 
100
101         L"January", L"February", L"March", L"April", L"May", L"June", L"July", L"August", L"September", L"October", L"November", L"December" 
102 };
103
104 FX_BOOL CJS_PublicMethods::IsNumber(FX_LPCWSTR string)
105 {
106         CFX_WideString sTrim = StrTrim(string);
107         FX_LPCWSTR pTrim = sTrim;
108         FX_LPCWSTR p = pTrim;
109
110
111         FX_BOOL bDot = FALSE;
112         FX_BOOL bKXJS = FALSE;
113
114         wchar_t c;
115         while ((c = *p))
116         {
117                 if (c == '.' || c == ',')
118                 {
119                         if (bDot) return FALSE;
120                         bDot = TRUE;
121                 }
122                 else if (c == '-' || c == '+')
123                 {
124                         if (p != pTrim)
125                                 return FALSE;
126                 }
127                 else if (c == 'e' || c == 'E')
128                 {
129                         if (bKXJS) return FALSE;
130
131                         p++;
132                         c = *p;
133                         if (c == '+' || c == '-')
134                         {
135                                 bKXJS = TRUE;
136                         }
137                         else
138                         {
139                                 return FALSE;
140                         }
141                 }
142                 else if (!IsDigit(c))
143                 {
144                         return FALSE;
145                 }
146                 p++;
147         }
148
149         return TRUE;
150 }
151
152 FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch)
153 {
154         return (ch >= L'0' && ch <= L'9');
155 }
156
157 FX_BOOL CJS_PublicMethods::IsDigit(char ch)
158 {
159         return (ch >= '0' && ch <= '9');
160 }
161
162 FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch)
163 {
164         return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));
165 }
166
167 FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch)
168 {
169         return (IsDigit(ch) || IsAlphabetic(ch));
170 }
171
172 FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change,wchar_t c_Mask)
173 {
174         switch (c_Mask)
175         {
176         case L'9':
177         return IsDigit(c_Change);               
178     case L'A':
179         return IsAlphabetic(c_Change);          
180     case L'O':
181         return IsAlphaNumeric(c_Change);                
182     case L'X':
183         return TRUE;            
184         default:
185         return (c_Change == c_Mask);
186         }
187 }
188
189 FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch)
190 {
191         return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
192 }
193
194 double CJS_PublicMethods::AF_Simple(FX_LPCWSTR sFuction, double dValue1, double dValue2)
195 {
196         if (FXSYS_wcsicmp(sFuction,L"AVG") == 0 || FXSYS_wcsicmp(sFuction,L"SUM") == 0)
197         {
198                 return dValue1 + dValue2;
199         }
200         else if (FXSYS_wcsicmp(sFuction, L"PRD") == 0)
201         {
202                 return dValue1 * dValue2;
203         }
204         else if (FXSYS_wcsicmp(sFuction,L"MIN") == 0)
205         {
206                 return FX_MIN(dValue1, dValue2);
207         }
208         else if (FXSYS_wcsicmp(sFuction,L"MAX") == 0)
209         {
210                 return FX_MAX(dValue1, dValue2);
211         }
212
213         return dValue1;
214 }
215
216 CFX_WideString CJS_PublicMethods::StrLTrim(FX_LPCWSTR pStr)
217 {
218         while (*pStr && *pStr == L' ') pStr++;
219
220         return pStr;
221 }
222
223 CFX_WideString CJS_PublicMethods::StrRTrim(FX_LPCWSTR pStr)
224 {
225         FX_LPCWSTR p = pStr;
226         while (*p) p++;
227         while (p > pStr && *(p - 1) == L' ') p--;
228
229         return CFX_WideString(pStr, p - pStr);
230 }
231
232 CFX_WideString CJS_PublicMethods::StrTrim(FX_LPCWSTR pStr)
233 {
234         return StrRTrim(StrLTrim(pStr));
235 }
236
237 CFX_ByteString CJS_PublicMethods::StrLTrim(FX_LPCSTR pStr)
238 {
239         while (*pStr && *pStr == ' ') pStr++;
240
241         return pStr;
242 }
243
244 CFX_ByteString CJS_PublicMethods::StrRTrim(FX_LPCSTR pStr)
245 {
246         FX_LPCSTR p = pStr;
247         while (*p) p++;
248         while (p > pStr && *(p - 1) == L' ') p--;
249
250         return CFX_ByteString(pStr,p-pStr);
251 }
252
253 CFX_ByteString CJS_PublicMethods::StrTrim(FX_LPCSTR pStr)
254 {
255         return StrRTrim(StrLTrim(pStr));
256 }
257
258 double CJS_PublicMethods::ParseNumber(FX_LPCWSTR swSource, FX_BOOL& bAllDigits, FX_BOOL& bDot, FX_BOOL& bSign, FX_BOOL& bKXJS)
259 {
260         bDot = FALSE;
261         bSign = FALSE;
262         bKXJS = FALSE;
263
264         FX_BOOL bDigitExist = FALSE;
265
266         FX_LPCWSTR p = swSource;
267         wchar_t c;
268
269         FX_LPCWSTR pStart = NULL;
270         FX_LPCWSTR pEnd = NULL;
271
272         while ((c = *p))
273         {
274                 if (!pStart && c != L' ')
275                 {
276                         pStart = p;
277                 }
278
279                 pEnd = p;
280                 p++;
281         }
282
283         if (!pStart)
284         {
285                 bAllDigits = FALSE;
286                 return 0;
287         }
288
289         while (pEnd != pStart)
290         {
291                 if (*pEnd == L' ')
292                         pEnd --;
293                 else
294                         break;
295         }
296
297         double dRet = 0;
298         p = pStart;
299         bAllDigits = TRUE;
300         CFX_WideString swDigits;
301
302         while (p <= pEnd)
303         {       
304                 c = *p;
305
306                 if (IsDigit(c))
307                 {
308                         swDigits += c;
309                         bDigitExist = TRUE;
310                 }
311                 else 
312                 {
313                         switch (c)
314                         {
315                         case L' ':
316                                 bAllDigits = FALSE;
317                                 break;
318                         case L'.':
319                         case L',':
320                                 if (!bDot)
321                                 {
322                                         if (bDigitExist)
323                                         {
324                                                 swDigits += L'.';
325                                         }
326                                         else
327                                         {
328                                                 swDigits += L'0';
329                                                 swDigits += L'.';
330                                                 bDigitExist = TRUE;
331                                         }
332
333                                         bDot = TRUE;
334                                         break;
335                                 }
336                         case 'e':
337                         case 'E':
338                                 if (!bKXJS)
339                                 {
340                                         p++;
341                                         c = *p;
342                                         if (c == '+' || c == '-')
343                                         {
344                                                 bKXJS = TRUE;
345                                                 swDigits += 'e';
346                                                 swDigits += c;
347                                         }
348                                         break;
349                                 }
350                         case L'-':
351                                 if (!bDigitExist && !bSign)
352                                 {
353                                         swDigits += c;
354                                         bSign = TRUE;
355                                         break;
356                                 }
357                         default:
358                                 bAllDigits = FALSE;
359
360                                 if (p != pStart && !bDot && bDigitExist)
361                                 {
362                                         swDigits += L'.';
363                                         bDot = TRUE;
364                                 }
365                                 else
366                                 {
367                                         bDot = FALSE;
368                                         bDigitExist = FALSE;
369                                         swDigits = L"";
370                                 }
371                                 break;
372                         }
373                 }
374
375                 p++;
376         }
377
378         if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17)
379         {
380                 CFX_ByteString sDigits = swDigits.UTF8Encode();
381
382                 if (bKXJS)
383                 {
384                         dRet = atof(sDigits);
385                 }
386                 else
387                 {
388                         if (bDot)
389                         {
390                                 char* pStopString;
391                                 dRet = ::strtod(sDigits, &pStopString);
392                         }
393                         else
394                         {
395                                 dRet = atol(sDigits);
396                         }
397                 }
398
399         }
400
401         return dRet;
402 }
403
404 double CJS_PublicMethods::ParseStringToNumber(FX_LPCWSTR swSource)
405 {
406         FX_BOOL bAllDigits = FALSE;
407         FX_BOOL bDot = FALSE;
408         FX_BOOL bSign = FALSE;
409         FX_BOOL bKXJS = FALSE;
410
411         return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
412 }
413
414 FX_BOOL CJS_PublicMethods::ConvertStringToNumber(FX_LPCWSTR swSource, double & dRet, FX_BOOL & bDot)
415 {
416         FX_BOOL bAllDigits = FALSE;
417         FX_BOOL bSign = FALSE;
418         FX_BOOL bKXJS = FALSE;
419
420         dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
421
422         return bAllDigits;
423 }
424
425 CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(v8::Isolate* isolate, CJS_Value val)
426 {
427         CJS_Array StrArray(isolate);
428         if(val.IsArrayObject())
429         {
430                 val.ConvertToArray(StrArray);
431                 return StrArray;
432         }
433         CFX_WideString wsStr = val.operator CFX_WideString();
434         CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
435         const char * p = (const char *)t;
436
437
438         int ch = ',' ;
439         int nIndex = 0;
440
441         while (*p)
442         {
443                 const char * pTemp = strchr(p, ch);
444                 if (pTemp == NULL)
445                 {
446                         StrArray.SetElement(nIndex, CJS_Value(isolate,(FX_LPCSTR)StrTrim(p)));
447                         break;
448                 }
449                 else
450                 {
451                         char * pSub = new char[pTemp - p + 1];
452                         strncpy(pSub, p, pTemp - p);
453                         *(pSub + (pTemp - p)) = '\0';
454
455                         StrArray.SetElement(nIndex, CJS_Value(isolate,(FX_LPCSTR)StrTrim(pSub)));
456                         delete []pSub;
457                         
458                         nIndex ++;
459                         p = ++pTemp;
460                 }
461                 
462         }
463         return StrArray;
464 }
465
466 int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,int nStart,int& nSkip, int nMaxStep)
467 {
468         int nRet = 0;
469         nSkip = 0;
470         for (int i=nStart, sz=string.GetLength(); i < sz; i++)
471         {
472                 if (i-nStart > 10)
473                         break;
474
475                 FX_WCHAR c = string.GetAt(i);
476                 if (IsDigit((wchar_t)c))
477                 {
478                         nRet = nRet * 10 + (c - '0');
479                         nSkip = i - nStart + 1;
480                         if (nSkip >= nMaxStep) 
481                                 break;
482                 }
483                 else
484                         break;
485         }
486
487         return nRet;
488 }
489
490 CFX_WideString CJS_PublicMethods::ParseStringString(const CFX_WideString& string, int nStart, int& nSkip)
491 {
492         CFX_WideString swRet;
493         nSkip = 0;
494         for (int i=nStart, sz=string.GetLength(); i < sz; i++)
495         {
496                 FX_WCHAR c = string.GetAt(i);
497                 if ((c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z'))
498                 {
499                         swRet += c;
500                         nSkip = i - nStart + 1;
501                 }
502                 else
503                         break;
504         }
505
506         return swRet;
507 }
508
509 double CJS_PublicMethods::ParseNormalDate(const CFX_WideString & value, FX_BOOL& bWrongFormat)
510 {
511         double dt = JS_GetDateTime();
512
513         int nYear = JS_GetYearFromTime(dt);
514         int nMonth = JS_GetMonthFromTime(dt) + 1;
515         int nDay = JS_GetDayFromTime(dt);
516         int nHour = JS_GetHourFromTime(dt);
517         int nMin = JS_GetMinFromTime(dt);
518         int nSec = JS_GetSecFromTime(dt);
519
520         int number[3];
521
522         int nSkip = 0;
523         int nLen = value.GetLength();
524         int nIndex = 0;
525         int i = 0;
526         while (i < nLen)
527         {
528                 if (nIndex > 2) break;
529
530                 FX_WCHAR c = value.GetAt(i);
531                 if (IsDigit((wchar_t)c))
532                 {
533                         number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
534                         i += nSkip;                     
535                 }
536                 else
537                 {
538                         i ++;
539                 }
540         }
541
542         if (nIndex == 2)
543         {
544                 // case2: month/day
545                 // case3: day/month
546                 if ((number[0] >= 1 && number[0] <= 12) && (number[1] >= 1 && number[1] <= 31))
547                 {
548                         nMonth = number[0];
549                         nDay = number[1];
550                 }
551                 else if ((number[0] >= 1 && number[0] <= 31) && (number[1] >= 1 && number[1] <= 12))
552                 {
553                         nDay = number[0];
554                         nMonth = number[1];
555                 }
556
557                 bWrongFormat = FALSE;
558         }
559         else if (nIndex == 3)
560         {
561                 // case1: year/month/day
562                 // case2: month/day/year
563                 // case3: day/month/year
564
565                 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) && (number[2] >= 1 && number[2] <= 31))
566                 {
567                         nYear = number[0];
568                         nMonth = number[1];
569                         nDay = number[2];
570                 }
571                 else if ((number[0] >= 1 && number[0] <= 12) && (number[1] >= 1 && number[1] <= 31) && number[2] > 31)
572                 {
573                         nMonth = number[0];
574                         nDay = number[1];
575                         nYear = number[2];
576                 }
577                 else if ((number[0] >= 1 && number[0] <= 31) && (number[1] >= 1 && number[1] <= 12) && number[2] > 31)
578                 {
579                         nDay = number[0];
580                         nMonth = number[1];
581                         nYear = number[2];
582                 }
583
584                 bWrongFormat = FALSE;
585         }
586         else
587         {
588                 bWrongFormat = TRUE;
589                 return dt;
590         }
591
592         CFX_WideString swTemp;
593         swTemp.Format(L"%d/%d/%d %d:%d:%d",nMonth,nDay,nYear,nHour,nMin,nSec);
594         return JS_DateParse(swTemp);
595 }
596
597 double CJS_PublicMethods::MakeRegularDate(const CFX_WideString & value, const CFX_WideString & format, FX_BOOL& bWrongFormat)
598 {
599         double dt = JS_GetDateTime();
600
601         if (format.IsEmpty() || value.IsEmpty())
602                 return dt;
603
604         int nYear = JS_GetYearFromTime(dt);
605         int nMonth = JS_GetMonthFromTime(dt) + 1;
606         int nDay = JS_GetDayFromTime(dt);
607         int nHour = JS_GetHourFromTime(dt);
608         int nMin = JS_GetMinFromTime(dt);
609         int nSec = JS_GetSecFromTime(dt);
610
611         int nYearSub = 99; //nYear - 2000;
612
613         FX_BOOL bPm = FALSE;
614         FX_BOOL bExit = FALSE;
615         bWrongFormat = FALSE;
616
617         int i=0;
618         int j=0;
619
620         while (i < format.GetLength())
621         {
622                 if (bExit) break;
623
624                 FX_WCHAR c = format.GetAt(i);
625                 switch (c)
626                 {
627                         case ':':
628                         case '.':
629                         case '-':
630                         case '\\':
631                         case '/':
632                                 i++;
633                                 j++;
634                                 break;
635
636                         case 'y':
637                         case 'm':
638                         case 'd':
639                         case 'H':
640                         case 'h':
641                         case 'M':
642                         case 's':
643                         case 't':
644                                 {
645                                         int oldj = j;
646                                         int nSkip = 0;
647                                         int remaining = format.GetLength() - i - 1;
648
649                                         if (remaining == 0 || format.GetAt(i+1) != c)
650                                         {
651                                                 switch (c)
652                                                 {
653                                                         case 'y':
654                                                                 i++;
655                                                                 j++;
656                                                                 break;
657                                                         case 'm':
658                                                                 nMonth = ParseStringInteger(value, j, nSkip, 2);
659                                                                 i++;
660                                                                 j += nSkip;
661                                                                 break;
662                                                         case 'd':
663                                                                 nDay = ParseStringInteger(value, j, nSkip, 2);
664                                                                 i++;
665                                                                 j += nSkip;
666                                                                 break;
667                                                         case 'H':
668                                                                 nHour = ParseStringInteger(value, j, nSkip, 2);
669                                                                 i++;
670                                                                 j += nSkip;
671                                                                 break;
672                                                         case 'h':
673                                                                 nHour = ParseStringInteger(value, j, nSkip, 2);
674                                                                 i++;
675                                                                 j += nSkip;
676                                                                 break;
677                                                         case 'M':
678                                                                 nMin = ParseStringInteger(value, j, nSkip, 2);
679                                                                 i++;
680                                                                 j += nSkip;
681                                                                 break;
682                                                         case 's':
683                                                                 nSec = ParseStringInteger(value, j, nSkip, 2);
684                                                                 i++;
685                                                                 j += nSkip;
686                                                                 break;
687                                                         case 't':
688                                                                 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
689                                                                 i++;
690                                                                 j++;
691                                                                 break;
692                                                 }
693                                         }
694                                         else if (remaining == 1 || format.GetAt(i+2) != c)
695                                         {
696                                                 switch (c)
697                                                 {
698                                                         case 'y':
699                                                                 nYear = ParseStringInteger(value, j, nSkip, 4);
700                                                                 i += 2;
701                                                                 j += nSkip;
702                                                                 break;
703                                                         case 'm':
704                                                                 nMonth = ParseStringInteger(value, j, nSkip, 2);
705                                                                 i += 2;
706                                                                 j += nSkip;
707                                                                 break;
708                                                         case 'd':
709                                                                 nDay = ParseStringInteger(value, j, nSkip, 2);
710                                                                 i += 2;
711                                                                 j += nSkip;
712                                                                 break;
713                                                         case 'H':
714                                                                 nHour = ParseStringInteger(value, j, nSkip, 2);
715                                                                 i += 2;
716                                                                 j += nSkip;
717                                                                 break;
718                                                         case 'h':
719                                                                 nHour = ParseStringInteger(value, j, nSkip, 2);
720                                                                 i += 2;
721                                                                 j += nSkip;
722                                                                 break;
723                                                         case 'M':
724                                                                 nMin = ParseStringInteger(value, j, nSkip, 2);
725                                                                 i += 2;
726                                                                 j += nSkip;
727                                                                 break;
728                                                         case 's':
729                                                                 nSec = ParseStringInteger(value, j, nSkip, 2);
730                                                                 i += 2;
731                                                                 j += nSkip;
732                                                                 break;
733                                                         case 't':
734                                                                 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' && value.GetAt(j+1) == 'm');
735                                                                 i += 2;
736                                                                 j += 2;
737                                                                 break;
738                                                 }
739                                         }
740                                         else if (remaining == 2 || format.GetAt(i+3) != c)
741                                         {
742                                                 switch (c)
743                                                 {
744                                                         case 'm':
745                                                                 {
746                                                                         CFX_WideString sMonth = ParseStringString(value, j, nSkip);
747                                                                         FX_BOOL bFind = FALSE;
748                                                                         for (int m = 0; m < 12; m++)
749                                                                         {
750                                                                                 if (sMonth.CompareNoCase(months[m]) == 0)
751                                                                                 {
752                                                                                         nMonth = m + 1;
753                                                                                         i+=3;
754                                                                                         j+=nSkip;
755                                                                                         bFind = TRUE;
756                                                                                         break;
757                                                                                 }
758                                                                         }
759
760                                                                         if (!bFind)
761                                                                         {
762                                                                                 nMonth = ParseStringInteger(value, j, nSkip, 3);
763                                                                                 i+=3;
764                                                                                 j += nSkip;
765                                                                         }
766                                                                 }
767                                                                 break;
768                                                         case 'y':
769                                                                 break;
770                                                         default:
771                                                                 i+=3;
772                                                                 j+=3;
773                                                                 break;
774                                                 }
775                                         }
776                                         else if (remaining == 3 || format.GetAt(i+4) != c)
777                                         {
778                                                 switch (c)
779                                                 {
780
781
782                                                         case 'y':
783                                                                 nYear = ParseStringInteger(value, j, nSkip, 4);
784                                                                 j += nSkip;
785                                                                 i += 4;
786                                                                 break;
787                                                         case 'm':
788                                                                 {
789                                                                         FX_BOOL bFind = FALSE;
790
791                                                                         CFX_WideString sMonth = ParseStringString(value, j, nSkip);
792                                                                         sMonth.MakeLower();
793
794                                                                         for (int m = 0; m < 12; m++)
795                                                                         {
796                                                                                 CFX_WideString sFullMonths = fullmonths[m];
797                                                                                 sFullMonths.MakeLower();
798
799                                                                                 if (sFullMonths.Find(sMonth, 0) != -1)
800                                                                                 {
801                                                                                         nMonth = m + 1;
802                                                                                         i += 4;
803                                                                                         j += nSkip;
804                                                                                         bFind = TRUE;
805                                                                                         break;
806                                                                                 }
807                                                                         }
808
809                                                                         if (!bFind)
810                                                                         {
811                                                                                 nMonth = ParseStringInteger(value, j, nSkip, 4);
812                                                                                 i+=4;
813                                                                                 j += nSkip;
814                                                                         }
815                                                                 }
816                                                                 break;
817                                                         default:
818                                                                 i += 4;
819                                                                 j += 4;
820                                                                 break;
821                                                 }
822                                         }
823                                         else
824                                         {
825                                                 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j))
826                                                 {
827                                                         bWrongFormat = TRUE;
828                                                         bExit = TRUE;
829                                                 }
830                                                 i++;
831                                                 j++;
832                                         }
833
834                                         if (oldj == j)
835                                         {
836                                                 bWrongFormat = TRUE;
837                                                 bExit = TRUE;
838                                         }
839                                 }
840
841                                 break;
842                         default:
843                                 if (value.GetLength() <= j)
844                                 {
845                                         bExit = TRUE;
846                                 }
847                                 else if (format.GetAt(i) != value.GetAt(j))
848                                 {
849                                         bWrongFormat = TRUE;
850                                         bExit = TRUE;
851                                 }
852
853                                 i++;
854                                 j++;
855                                 break;
856                 }
857         }
858
859         if (bPm) nHour += 12;
860
861         if (nYear >= 0 && nYear <= nYearSub)
862                 nYear += 2000;
863
864         if (nMonth < 1 || nMonth > 12)
865                 bWrongFormat = TRUE;
866
867         if (nDay < 1 || nDay > 31)
868                 bWrongFormat = TRUE;
869
870         if (nHour < 0 || nHour > 24)
871                 bWrongFormat = TRUE;
872
873         if (nMin < 0 || nMin > 60)
874                 bWrongFormat = TRUE;
875
876         if (nSec < 0 || nSec > 60)
877                 bWrongFormat = TRUE;
878
879         double dRet = 0;
880
881         if (bWrongFormat)
882         {
883                 dRet = ParseNormalDate(value, bWrongFormat);
884         }
885         else
886         {
887                 dRet = JS_MakeDate(JS_MakeDay(nYear,nMonth - 1,nDay),JS_MakeTime(nHour, nMin, nSec, 0));
888
889                 if (JS_PortIsNan(dRet))
890                 {
891                         dRet = JS_DateParse(value);
892                 }
893         }
894
895         if (JS_PortIsNan(dRet))
896         {
897                 dRet = ParseNormalDate(value, bWrongFormat);
898         }
899
900         return dRet;
901
902 }
903
904 CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate, const CFX_WideString & format)
905 {
906         CFX_WideString sRet = L"",sPart = L"";
907
908         int nYear = JS_GetYearFromTime(dDate);
909         int nMonth = JS_GetMonthFromTime(dDate) + 1;
910         int nDay = JS_GetDayFromTime(dDate);
911         int nHour = JS_GetHourFromTime(dDate);
912         int nMin = JS_GetMinFromTime(dDate);
913         int nSec = JS_GetSecFromTime(dDate);
914
915         int i = 0;
916         while (i < format.GetLength())
917         {
918                 FX_WCHAR c = format.GetAt(i);
919                 int remaining = format.GetLength() - i - 1;
920                 sPart = L"";
921                 switch (c)
922                 {
923                         case 'y':
924                         case 'm':
925                         case 'd':
926                         case 'H':
927                         case 'h':
928                         case 'M':
929                         case 's':
930                         case 't':
931                                 if (remaining == 0 || format.GetAt(i+1) != c)
932                                 {
933                                         switch (c)
934                                         {
935                                                 case 'y':
936                                                         sPart += c;
937                                                         break;
938                                                 case 'm':
939                                                         sPart.Format(L"%d",nMonth);
940                                                         break;
941                                                 case 'd':
942                                                         sPart.Format(L"%d",nDay);
943                                                         break;
944                                                 case 'H':
945                                                         sPart.Format(L"%d",nHour);
946                                                         break;
947                                                 case 'h':
948                                                         sPart.Format(L"%d",nHour>12?nHour - 12:nHour);
949                                                         break;
950                                                 case 'M':
951                                                         sPart.Format(L"%d",nMin);
952                                                         break;
953                                                 case 's':
954                                                         sPart.Format(L"%d",nSec);
955                                                         break;
956                                                 case 't':
957                                                         sPart += nHour>12?'p':'a';
958                                                         break;
959                                         }
960                                         i++;
961                                 }
962                                 else if (remaining == 1 || format.GetAt(i+2) != c)
963                                 {
964                                         switch (c)
965                                         {
966                                                 case 'y':
967                                                         sPart.Format(L"%02d",nYear - (nYear / 100) * 100);
968                                                         break;
969                                                 case 'm':
970                                                         sPart.Format(L"%02d",nMonth);
971                                                         break;
972                                                 case 'd':
973                                                         sPart.Format(L"%02d",nDay);
974                                                         break;
975                                                 case 'H':
976                                                         sPart.Format(L"%02d",nHour);
977                                                         break;
978                                                 case 'h':
979                                                         sPart.Format(L"%02d",nHour>12?nHour - 12:nHour);
980                                                         break;
981                                                 case 'M':
982                                                         sPart.Format(L"%02d",nMin);
983                                                         break;
984                                                 case 's':
985                                                         sPart.Format(L"%02d",nSec);
986                                                         break;
987                                                 case 't':
988                                                         sPart = nHour>12? L"pm": L"am";
989                                                         break;
990                                         }
991                                         i+=2;
992                                 }
993                                 else if (remaining == 2 || format.GetAt(i+3) != c)
994                                 {
995                                         switch (c)
996                                         {
997                                                 case 'm':
998                                                         i+=3;
999                                                         if (nMonth > 0&&nMonth <= 12)
1000                                                                 sPart += months[nMonth - 1];
1001                                                         break;
1002                                                 default:
1003                                                         i+=3;
1004                                                         sPart += c;
1005                                                         sPart += c;
1006                                                         sPart += c;
1007                                                         break;
1008                                         }
1009                                 }
1010                                 else if (remaining == 3 || format.GetAt(i+4) != c)
1011                                 {
1012                                         switch (c)
1013                                         {
1014                                                 case 'y':
1015                                                         sPart.Format(L"%04d",nYear);
1016                                                         i += 4;
1017                                                         break;
1018                                                 case 'm':
1019                                                         i+=4;
1020                                                         if (nMonth > 0&&nMonth <= 12)
1021                                                                 sPart += fullmonths[nMonth - 1];
1022                                                         break;
1023                                                 default:
1024                                                         i += 4;
1025                                                         sPart += c;
1026                                                         sPart += c;
1027                                                         sPart += c;
1028                                                         sPart += c;
1029                                                         break;
1030                                         }
1031                                 }
1032                                 else
1033                                 {
1034                                         i++;
1035                                         sPart += c;
1036                                 }
1037                                 break;
1038                         default:
1039                                 i++;
1040                                 sPart += c;
1041                                 break;
1042                 }
1043
1044                 sRet += sPart;
1045         }
1046
1047         return sRet;
1048 }
1049
1050 /* -------------------------------------------------------------------------- */
1051
1052 //function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)
1053 FX_BOOL CJS_PublicMethods::AFNumber_Format(OBJ_METHOD_PARAMS)
1054 {
1055 #if _FX_OS_ != _FX_ANDROID_
1056         v8::Isolate* isolate = ::GetIsolate(cc);
1057         CJS_Context* pContext = (CJS_Context *)cc;
1058         ASSERT(pContext != NULL);
1059         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1060         ASSERT(pEvent != NULL);
1061
1062         if (params.size() != 6)
1063         {
1064                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1065                 return FALSE;
1066         }
1067         if(!pEvent->m_pValue)
1068                 return FALSE;
1069         CFX_WideString& Value = pEvent->Value();        
1070         CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1071         
1072         if (strValue.IsEmpty()) return TRUE;
1073         
1074         int iDec = params[0];
1075         int iSepStyle = params[1];
1076         int iNegStyle = params[2];
1077         // params[3] is iCurrStyle, it's not used.
1078         std::wstring wstrCurrency(params[4].operator CFX_WideString());
1079         FX_BOOL bCurrencyPrepend = params[5];
1080         
1081         if (iDec < 0) iDec = -iDec;
1082         
1083         if (iSepStyle < 0 || iSepStyle > 3)
1084                 iSepStyle = 0;
1085         
1086         if (iNegStyle < 0 || iNegStyle > 3)
1087                 iNegStyle = 0;
1088         
1089         
1090         //////////////////////////////////////////////////////
1091         //for processing decimal places
1092         strValue.Replace(",", ".");
1093         double dValue = atof(strValue);
1094         if (iDec > 0)
1095                 dValue += DOUBLE_CORRECT;//
1096                     
1097         int iDec2;
1098         FX_BOOL bNagative = FALSE;
1099
1100         strValue = fcvt(dValue,iDec,&iDec2,&bNagative);
1101         if (strValue.IsEmpty())
1102         {
1103                 dValue = 0;
1104                 strValue = fcvt(dValue,iDec,&iDec2,&bNagative);
1105                 if (strValue.IsEmpty())
1106                 {
1107                         strValue = "0";
1108                         iDec2 = 1;
1109                 }
1110
1111         }
1112
1113         if (iDec2 < 0)
1114         {
1115                 for (int iNum = 0;iNum < abs(iDec2);iNum++)
1116                 {
1117                         strValue = "0" + strValue;
1118                 }
1119                 iDec2 = 0;
1120                 
1121         }
1122         int iMax = strValue.GetLength();
1123         if (iDec2 > iMax)
1124         {
1125                 for (int iNum = 0;iNum <= iDec2 - iMax ;iNum++)
1126                 {
1127                         strValue += "0";
1128                 }
1129                 iMax = iDec2+1;                 
1130         }
1131         ///////////////////////////////////////////////////////
1132     //for processing seperator style
1133         if (iDec2 < iMax)
1134         {
1135                 if (iSepStyle == 0 || iSepStyle == 1)
1136                 {
1137                         strValue.Insert(iDec2, '.');
1138                         iMax++;
1139                 }
1140                 else if (iSepStyle == 2 || iSepStyle == 3)
1141                 {
1142                         strValue.Insert(iDec2, ',');
1143                         iMax++;
1144                 }
1145                 
1146                 if (iDec2 == 0)
1147                         strValue.Insert(iDec2, '0');
1148         }
1149         if (iSepStyle == 0 || iSepStyle == 2)
1150         {
1151                 char cSeperator;
1152                 if (iSepStyle == 0)
1153                         cSeperator = ',';
1154                 else
1155                         cSeperator = '.';
1156                 
1157                 int iDecPositive,iDecNagative;
1158                 iDecPositive = iDec2;
1159                 iDecNagative = iDec2;           
1160                 
1161                 for (iDecPositive = iDec2 -3; iDecPositive > 0;iDecPositive -= 3)
1162                 {
1163                         strValue.Insert(iDecPositive, cSeperator);
1164                         iMax++;
1165                 }
1166         }
1167         
1168         //////////////////////////////////////////////////////////////////////
1169     //for processing currency string
1170
1171         Value = CFX_WideString::FromLocal(strValue);
1172         
1173         std::wstring strValue2(Value);
1174
1175         if (bCurrencyPrepend)
1176                 strValue2 = wstrCurrency + strValue2;
1177         else
1178                 strValue2 = strValue2 + wstrCurrency;
1179         
1180         
1181         
1182         /////////////////////////////////////////////////////////////////////////
1183         //for processing negative style
1184         if (bNagative)
1185         {
1186                 if (iNegStyle == 0)
1187                 {
1188                         strValue2.insert(0,L"-");
1189                 }
1190                 if (iNegStyle == 2 || iNegStyle == 3)
1191                 {
1192                         strValue2.insert(0,L"(");
1193                         strValue2.insert(strValue2.length(),L")");
1194                 }
1195                 if (iNegStyle == 1 || iNegStyle == 3)
1196                 {
1197                         if (Field * fTarget = pEvent->Target_Field())
1198                         {
1199                                 CJS_Array arColor(isolate);
1200                                 CJS_Value vColElm(isolate);
1201                                 vColElm = L"RGB";
1202                                 arColor.SetElement(0,vColElm);
1203                                 vColElm = 1;
1204                                 arColor.SetElement(1,vColElm);
1205                                 vColElm = 0;
1206                                 arColor.SetElement(2,vColElm);
1207                                 
1208                                 arColor.SetElement(3,vColElm);
1209                                 
1210                                 CJS_PropValue vProp(isolate);
1211                                 vProp.StartGetting();
1212                                 vProp<<arColor;
1213                                 vProp.StartSetting();
1214                                 fTarget->textColor(cc,vProp,sError);// red
1215                         }
1216                 }
1217         }
1218         else
1219         {
1220                 if (iNegStyle == 1 || iNegStyle == 3)
1221                 {
1222                         if (Field *fTarget = pEvent->Target_Field())
1223                         {
1224                                 CJS_Array arColor(isolate);
1225                                 CJS_Value vColElm(isolate);
1226                                 vColElm = L"RGB";
1227                                 arColor.SetElement(0,vColElm);
1228                                 vColElm = 0;
1229                                 arColor.SetElement(1,vColElm);
1230                                 arColor.SetElement(2,vColElm);
1231                                 arColor.SetElement(3,vColElm);
1232                                 
1233                                 CJS_PropValue vProp(isolate);
1234                                 vProp.StartGetting();
1235                                 fTarget->textColor(cc,vProp,sError);
1236                                 
1237                                 CJS_Array aProp(isolate);
1238                                 vProp.ConvertToArray(aProp);
1239
1240                                 CPWL_Color crProp;
1241                                 CPWL_Color crColor;
1242                                 color::ConvertArrayToPWLColor(aProp, crProp);
1243                                 color::ConvertArrayToPWLColor(arColor, crColor);
1244
1245                                 if (crColor != crProp)
1246                                 {
1247                                         CJS_PropValue vProp2(isolate);
1248                                         vProp2.StartGetting();
1249                                         vProp2<<arColor;
1250                                         vProp2.StartSetting();
1251                                 fTarget->textColor(cc,vProp2,sError);
1252                                 }
1253                         }
1254                 }
1255         }
1256         Value = strValue2.c_str();
1257 #endif
1258         return TRUE;
1259 }
1260
1261 //function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)
1262 FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(OBJ_METHOD_PARAMS)
1263 {
1264         CJS_Context* pContext = (CJS_Context *)cc;
1265         ASSERT(pContext != NULL);
1266         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1267         ASSERT(pEvent != NULL);
1268         
1269         if(params.size() < 2)
1270                 return FALSE;
1271         int iSepStyle = params[1];
1272         
1273         if (iSepStyle < 0 || iSepStyle > 3)
1274                 iSepStyle = 0;
1275         if(!pEvent->m_pValue)
1276                 return FALSE;
1277         CFX_WideString & val = pEvent->Value(); 
1278         CFX_WideString & w_strChange = pEvent->Change();
1279     CFX_WideString w_strValue = val;
1280
1281         if (pEvent->WillCommit())
1282         {
1283                 CFX_WideString wstrChange = w_strChange;
1284                 CFX_WideString wstrValue = StrLTrim(w_strValue);
1285                 if (wstrValue.IsEmpty())
1286                         return TRUE;
1287                 
1288                 CFX_WideString swTemp = wstrValue;
1289                 swTemp.Replace(L",", L".");
1290                 if (!IsNumber(swTemp)) //!(IsNumber(wstrChange) && 
1291                 {
1292                         pEvent->Rc() = FALSE;
1293                         sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1294                         Alert(pContext, sError);
1295                         return TRUE;
1296                 }
1297                 return TRUE; // it happens after the last keystroke and before validating,
1298         }
1299         
1300         std::wstring w_strValue2 (w_strValue);
1301         std::wstring w_strChange2(w_strChange);
1302         
1303         std::wstring w_strSelected;
1304         if(-1 != pEvent->SelStart())
1305                 w_strSelected = w_strValue2.substr(pEvent->SelStart(),(pEvent->SelEnd() - pEvent->SelStart()));
1306         FX_BOOL bHasSign = (w_strValue2.find('-') != -1) && (w_strSelected.find('-') == -1);
1307         if (bHasSign)
1308         {
1309                 //can't insert "change" in front to sign postion.
1310                 if (pEvent->SelStart() == 0)
1311                 {
1312             FX_BOOL &bRc = pEvent->Rc();
1313                         bRc = FALSE;
1314                         return TRUE;
1315                 }
1316         }
1317
1318         char cSep = L'.';
1319
1320         switch (iSepStyle)
1321         {
1322         case 0:
1323         case 1:
1324                 cSep = L'.';
1325                 break;
1326         case 2:
1327         case 3:
1328                 cSep = L',';
1329                 break;
1330         }
1331         
1332         FX_BOOL bHasSep = (w_strValue2.find(cSep) != -1);
1333         for (std::wstring::iterator it = w_strChange2.begin(); it != w_strChange2.end(); it++)
1334         {
1335                 if (*it == cSep)
1336                 {
1337                         if (bHasSep)
1338                         {
1339                                 FX_BOOL &bRc = pEvent->Rc();
1340                                 bRc = FALSE;
1341                                 return TRUE;
1342                         }
1343                         else
1344                         {
1345                                 bHasSep = TRUE;
1346                                 continue;
1347                         }
1348                 }
1349                 if (*it == L'-')
1350                 {
1351                         if (bHasSign)
1352                         {
1353                                 FX_BOOL &bRc = pEvent->Rc();
1354                                 bRc = FALSE;
1355                                 return TRUE;
1356                         }
1357                         else if (it != w_strChange2.begin()) //sign's position is not correct
1358                         {
1359                                 FX_BOOL &bRc = pEvent->Rc();
1360                                 bRc = FALSE;
1361                                 return TRUE;
1362                         }
1363                         else if (pEvent->SelStart() != 0)
1364                         {
1365                                 FX_BOOL &bRc = pEvent->Rc();
1366                                 bRc = FALSE;
1367                                 return TRUE;
1368                         }
1369                         bHasSign = TRUE;
1370                         continue;
1371                 }
1372                 
1373                 if (!IsDigit(*it))
1374                 {                       
1375                         FX_BOOL &bRc = pEvent->Rc();
1376                         bRc = FALSE;
1377                         return TRUE;
1378                 }
1379         }
1380         
1381         
1382         std::wstring w_prefix = w_strValue2.substr(0,pEvent->SelStart());
1383         std::wstring w_postfix;
1384         if (pEvent->SelEnd()<(int)w_strValue2.length())
1385                 w_postfix  = w_strValue2.substr(pEvent->SelEnd());
1386         w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1387         w_strValue = w_strValue2.c_str();
1388         val = w_strValue;
1389         return TRUE;            
1390         
1391 }
1392
1393 //function AFPercent_Format(nDec, sepStyle)
1394 FX_BOOL CJS_PublicMethods::AFPercent_Format(OBJ_METHOD_PARAMS)
1395 {
1396 #if _FX_OS_ != _FX_ANDROID_
1397         CJS_Context* pContext = (CJS_Context *)cc;
1398         ASSERT(pContext != NULL);
1399         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1400         ASSERT(pEvent != NULL);
1401
1402     if (params.size() != 2)
1403         {
1404                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1405                 return FALSE;
1406         }
1407         if(!pEvent->m_pValue)
1408                 return FALSE;
1409         CFX_WideString& Value = pEvent->Value();
1410         
1411 //     HWND hMainFrame = NULL;
1412 //      
1413 //      CPDFSDK_FormFillApp *pApp = pContext->GetReaderApp();
1414 //      ASSERT(pApp);
1415 //      hMainFrame = pApp->GetMainFrameWnd();
1416                 
1417         CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1418         
1419         if (strValue.IsEmpty())
1420                 return TRUE;
1421         
1422         int iDec = params[0];
1423         int iSepStyle = params[1];
1424         
1425         //ASSERT(iDec > 0);
1426         if (iDec < 0)
1427                 iDec = -iDec;
1428         
1429         if (iSepStyle < 0 || iSepStyle > 3)
1430                 iSepStyle = 0;
1431         
1432         
1433         //////////////////////////////////////////////////////
1434         //for processing decimal places
1435         double dValue = atof(strValue);
1436         dValue *= 100;
1437         if (iDec > 0)
1438                 dValue += DOUBLE_CORRECT;//УÕý
1439
1440         int iDec2;
1441         FX_BOOL bNagative = FALSE;
1442         strValue = fcvt(dValue,iDec,&iDec2,&bNagative);
1443     if (strValue.IsEmpty())
1444         {
1445                 dValue = 0;
1446                 strValue = fcvt(dValue,iDec,&iDec2,&bNagative);
1447         }
1448
1449         if (iDec2 < 0)
1450         {
1451                 for (int iNum = 0; iNum < abs(iDec2); iNum++)
1452                 {
1453                         strValue = "0" + strValue;
1454                 }
1455                 iDec2 = 0;
1456                 
1457         }
1458         int iMax = strValue.GetLength();
1459         if (iDec2 > iMax)
1460         {
1461                 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++)
1462                 {
1463                         strValue += "0";
1464                 }
1465                 iMax = iDec2+1;                 
1466         }
1467         ///////////////////////////////////////////////////////
1468     //for processing seperator style
1469         if (iDec2 < iMax)
1470         {
1471                 if (iSepStyle == 0 || iSepStyle == 1)
1472                 {
1473                         strValue.Insert(iDec2, '.');
1474                         iMax++;
1475                 }
1476                 else if (iSepStyle == 2 || iSepStyle == 3)
1477                 {
1478                         strValue.Insert(iDec2, ',');
1479                         iMax++;
1480                 }
1481                 
1482                 if (iDec2 == 0)
1483                         strValue.Insert(iDec2, '0');
1484         }
1485         if (iSepStyle == 0 || iSepStyle == 2)
1486         {
1487                 char cSeperator;
1488                 if (iSepStyle == 0)
1489                         cSeperator = ',';
1490                 else
1491                         cSeperator = '.';
1492                 
1493                 int iDecPositive,iDecNagative;
1494                 iDecPositive = iDec2;
1495                 iDecNagative = iDec2;
1496                         
1497                 for (iDecPositive = iDec2 -3; iDecPositive > 0; iDecPositive -= 3)
1498                 {
1499                         strValue.Insert(iDecPositive,cSeperator);
1500                         iMax++;
1501                 }
1502         }
1503         ////////////////////////////////////////////////////////////////////
1504         //nagative mark
1505         if(bNagative)
1506                 strValue = "-" + strValue;
1507         strValue += "%";
1508         Value = CFX_WideString::FromLocal(strValue);
1509 #endif
1510         return TRUE;
1511 }
1512 //AFPercent_Keystroke(nDec, sepStyle)
1513 FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(OBJ_METHOD_PARAMS)
1514 {
1515         return AFNumber_Keystroke(cc,params,vRet,sError);
1516 }
1517
1518 //function AFDate_FormatEx(cFormat)
1519 FX_BOOL CJS_PublicMethods::AFDate_FormatEx(OBJ_METHOD_PARAMS)
1520 {
1521         CJS_Context* pContext = (CJS_Context *)cc;
1522         ASSERT(pContext != NULL);
1523         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1524         ASSERT(pEvent != NULL);
1525
1526         if (params.size() != 1)
1527         {
1528                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1529                 return FALSE;
1530         }       
1531         if(!pEvent->m_pValue)
1532                 return FALSE;
1533         CFX_WideString& val = pEvent->Value();
1534         
1535         CFX_WideString strValue = val;  
1536         if (strValue.IsEmpty()) return TRUE;            
1537
1538         CFX_WideString sFormat = params[0].operator CFX_WideString();
1539
1540         FX_BOOL bWrongFormat = FALSE;
1541         double dDate = 0.0f;
1542
1543         if(strValue.Find(L"GMT") != -1)
1544         {
1545                 //for GMT format time
1546                 //such as "Tue Aug 11 14:24:16 GMT+08002009"
1547                 dDate = MakeInterDate(strValue);
1548         }
1549         else
1550         {
1551                 dDate = MakeRegularDate(strValue,sFormat,bWrongFormat);
1552         }
1553
1554         if (JS_PortIsNan(dDate))
1555         {
1556                 CFX_WideString swMsg;
1557                 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE), (FX_LPCWSTR)sFormat);
1558                 Alert(pContext, swMsg);
1559                 return FALSE;
1560         }
1561         
1562         val =  MakeFormatDate(dDate,sFormat);
1563
1564         return TRUE;
1565 }
1566
1567 double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue)
1568 {
1569         int nHour;
1570         int nMin;
1571         int nSec;
1572         int nYear;
1573         int nMonth;
1574         int nDay;
1575
1576         CFX_WideStringArray wsArray;
1577         CFX_WideString sMonth = L"";
1578         CFX_WideString sTemp = L"";
1579         int nSize = strValue.GetLength();
1580
1581         for(int i = 0; i < nSize; i++)
1582         {
1583                 FX_WCHAR c = strValue.GetAt(i);
1584                 if(c == L' ' || c == L':')
1585                 {       
1586                         wsArray.Add(sTemp);
1587                         sTemp = L"";
1588                         continue;
1589                 }
1590
1591                 sTemp += c;
1592         }
1593         
1594         wsArray.Add(sTemp);
1595         if(wsArray.GetSize() != 8)return 0;
1596
1597         sTemp = wsArray[1];
1598         if(sTemp.Compare(L"Jan") == 0) nMonth = 1;
1599         if(sTemp.Compare(L"Feb") == 0) nMonth = 2;
1600         if(sTemp.Compare(L"Mar") == 0) nMonth = 3;
1601         if(sTemp.Compare(L"Apr") == 0) nMonth = 4;
1602         if(sTemp.Compare(L"May") == 0) nMonth = 5;
1603         if(sTemp.Compare(L"Jun") == 0) nMonth = 6;
1604         if(sTemp.Compare(L"Jul") == 0) nMonth = 7;
1605         if(sTemp.Compare(L"Aug") == 0) nMonth = 8;
1606         if(sTemp.Compare(L"Sep") == 0) nMonth = 9;
1607         if(sTemp.Compare(L"Oct") == 0) nMonth = 10;
1608         if(sTemp.Compare(L"Nov") == 0) nMonth = 11;
1609         if(sTemp.Compare(L"Dec") == 0) nMonth = 12;
1610
1611         nDay = (int)ParseStringToNumber(wsArray[2]);
1612         nHour = (int)ParseStringToNumber(wsArray[3]);
1613         nMin = (int)ParseStringToNumber(wsArray[4]);
1614         nSec = (int)ParseStringToNumber(wsArray[5]);
1615         nYear = (int)ParseStringToNumber(wsArray[7]);
1616
1617         double dRet = JS_MakeDate(JS_MakeDay(nYear,nMonth - 1,nDay),JS_MakeTime(nHour, nMin, nSec, 0));
1618
1619         if (JS_PortIsNan(dRet))
1620         {
1621                 dRet = JS_DateParse(strValue);
1622         }
1623         
1624         return dRet;
1625 }
1626
1627 //AFDate_KeystrokeEx(cFormat)
1628 FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(OBJ_METHOD_PARAMS)
1629 {
1630         CJS_Context* pContext = (CJS_Context *)cc;
1631         ASSERT(pContext != NULL);
1632         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1633         ASSERT(pEvent != NULL);
1634
1635         if (params.size() != 1)
1636         {
1637                 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1638                 return FALSE;
1639         }       
1640         
1641         if (pEvent->WillCommit())
1642         {
1643                 if(!pEvent->m_pValue)
1644                         return FALSE;
1645                 CFX_WideString strValue = pEvent->Value();
1646                 if (strValue.IsEmpty()) return TRUE;
1647
1648                 CFX_WideString sFormat = params[0].operator CFX_WideString();
1649
1650                 FX_BOOL bWrongFormat = FALSE;
1651                 double dRet = MakeRegularDate(strValue,sFormat,bWrongFormat);
1652                 if (bWrongFormat || JS_PortIsNan(dRet))
1653                 {
1654                         CFX_WideString swMsg;
1655                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE), (FX_LPCWSTR)sFormat);
1656                         Alert(pContext, swMsg);
1657                         pEvent->Rc() = FALSE;
1658                         return TRUE;
1659                 }
1660         }
1661         return TRUE;
1662 }
1663
1664 FX_BOOL CJS_PublicMethods::AFDate_Format(OBJ_METHOD_PARAMS)
1665 {
1666         v8::Isolate* isolate = ::GetIsolate(cc);
1667
1668         if (params.size() != 1)
1669         {
1670                 CJS_Context* pContext = (CJS_Context*)cc;
1671                 ASSERT(pContext != NULL);
1672
1673                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1674                 return FALSE;
1675         }
1676
1677         int iIndex = params[0];
1678         FX_LPCWSTR cFormats[] =  {L"m/d", L"m/d/yy", L"mm/dd/yy", L"mm/yy", L"d-mmm", L"d-mmm-yy", L"dd-mmm-yy",
1679                 L"yy-mm-dd", L"mmm-yy", L"mmmm-yy", L"mmm d, yyyy", L"mmmm d, yyyy",
1680                 L"m/d/yy h:MM tt", L"m/d/yy HH:MM" };
1681
1682         ASSERT(iIndex < sizeof(cFormats)/sizeof(FX_LPCWSTR));
1683
1684         if (iIndex < 0)
1685                 iIndex = 0;
1686         if (iIndex >= sizeof(cFormats)/sizeof(FX_LPCWSTR))
1687                 iIndex = 0;
1688         CJS_Parameters newParams;
1689         CJS_Value val(isolate,cFormats[iIndex]);
1690         newParams.push_back(val);
1691         return AFDate_FormatEx(cc,newParams,vRet,sError);
1692 }
1693
1694 //AFDate_KeystrokeEx(cFormat)
1695 FX_BOOL CJS_PublicMethods::AFDate_Keystroke(OBJ_METHOD_PARAMS)
1696 {
1697         v8::Isolate* isolate = ::GetIsolate(cc);
1698
1699         if (params.size() != 1)
1700         {
1701                 CJS_Context* pContext = (CJS_Context*)cc;
1702                 ASSERT(pContext != NULL);
1703
1704                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1705                 return FALSE;
1706         }
1707
1708         int iIndex = params[0];
1709         FX_LPCWSTR cFormats[] =  {L"m/d", L"m/d/yy", L"mm/dd/yy", L"mm/yy", L"d-mmm", L"d-mmm-yy", L"dd-mmm-yy",
1710                 L"yy-mm-dd", L"mmm-yy", L"mmmm-yy", L"mmm d, yyyy", L"mmmm d, yyyy",
1711                 L"m/d/yy h:MM tt", L"m/d/yy HH:MM" };
1712
1713         ASSERT(iIndex<sizeof(cFormats)/sizeof(FX_LPCWSTR));
1714
1715         if (iIndex < 0)
1716                 iIndex = 0;
1717         if (iIndex >= sizeof(cFormats)/sizeof(FX_LPCWSTR))
1718                 iIndex = 0;
1719         CJS_Parameters newParams;
1720         CJS_Value val(isolate,cFormats[iIndex]);
1721         newParams.push_back(val);
1722         return AFDate_KeystrokeEx(cc,newParams,vRet,sError);
1723 }
1724
1725 //function AFTime_Format(ptf)
1726 FX_BOOL CJS_PublicMethods::AFTime_Format(OBJ_METHOD_PARAMS)
1727 {
1728         v8::Isolate* isolate = ::GetIsolate(cc);
1729
1730         if (params.size() != 1)
1731         {
1732                 CJS_Context* pContext = (CJS_Context*)cc;
1733                 ASSERT(pContext != NULL);
1734                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1735                 return FALSE;
1736         }
1737
1738         int iIndex = params[0];
1739         FX_LPCWSTR cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss", L"h:MM:ss tt"};
1740
1741         ASSERT(iIndex<sizeof(cFormats)/sizeof(FX_LPCWSTR));
1742
1743         if (iIndex < 0)
1744                 iIndex = 0;
1745         if (iIndex >= sizeof(cFormats)/sizeof(FX_LPCWSTR))
1746                 iIndex = 0;
1747         CJS_Parameters newParams;
1748         CJS_Value val(isolate,cFormats[iIndex]);
1749         newParams.push_back(val);
1750         return AFDate_FormatEx(cc,newParams,vRet,sError);
1751 }
1752
1753 FX_BOOL CJS_PublicMethods::AFTime_Keystroke(OBJ_METHOD_PARAMS)
1754 {
1755         v8::Isolate* isolate = ::GetIsolate(cc);
1756         if (params.size() != 1)
1757         {
1758                 CJS_Context* pContext = (CJS_Context*)cc;
1759                 ASSERT(pContext != NULL);
1760                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1761                 return FALSE;
1762         }
1763
1764         int iIndex = params[0];
1765         FX_LPCWSTR cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss", L"h:MM:ss tt"};
1766
1767         ASSERT(iIndex<sizeof(cFormats)/sizeof(FX_LPCWSTR));
1768
1769         if (iIndex < 0)
1770                 iIndex = 0;
1771         if (iIndex >= sizeof(cFormats)/sizeof(FX_LPCWSTR))
1772                 iIndex = 0;
1773         CJS_Parameters newParams;
1774         CJS_Value val(isolate,cFormats[iIndex]);
1775         newParams.push_back(val);
1776         return AFDate_KeystrokeEx(cc,newParams,vRet,sError);
1777 }
1778
1779 FX_BOOL CJS_PublicMethods::AFTime_FormatEx(OBJ_METHOD_PARAMS)
1780 {
1781         return AFDate_FormatEx(cc,params,vRet,sError);
1782 }
1783
1784 FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(OBJ_METHOD_PARAMS)
1785 {
1786         return AFDate_KeystrokeEx(cc,params,vRet,sError);
1787 }
1788
1789 //function AFSpecial_Format(psf)
1790 FX_BOOL CJS_PublicMethods::AFSpecial_Format(OBJ_METHOD_PARAMS)
1791 {
1792         CJS_Context* pContext = (CJS_Context *)cc;
1793         ASSERT(pContext != NULL);
1794
1795         if (params.size() != 1)
1796         {
1797                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1798                 return FALSE;
1799         }
1800
1801         std::string cFormat;
1802         int iIndex = params[0];
1803
1804         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1805         ASSERT(pEvent != NULL);
1806
1807         if(!pEvent->m_pValue)
1808                 return FALSE;
1809         CFX_WideString& Value = pEvent->Value();        
1810         std::string strSrc = (FX_LPCSTR)CFX_ByteString::FromUnicode(Value);
1811         
1812         switch (iIndex) 
1813         {
1814         case 0:                         
1815                 cFormat = "99999";
1816                 break;
1817         case 1:                         
1818                 cFormat = "99999-9999";
1819                 break;
1820         case 2:                         
1821                 {
1822                         std::string NumberStr;
1823                         util::printx("9999999999", strSrc,NumberStr); 
1824                         if (NumberStr.length() >= 10 )
1825                                 cFormat = "(999) 999-9999";
1826                         else 
1827                                 cFormat = "999-9999";
1828                         break;
1829                 }
1830         case 3:
1831                 cFormat = "999-99-9999";
1832                 break;
1833         }
1834         
1835         std::string strDes;
1836         util::printx(cFormat,strSrc,strDes);
1837         Value = CFX_WideString::FromLocal(strDes.c_str());
1838         return TRUE;
1839 }
1840
1841
1842 //function AFSpecial_KeystrokeEx(mask)
1843 FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(OBJ_METHOD_PARAMS)
1844 {
1845         CJS_Context* pContext = (CJS_Context *)cc;
1846         ASSERT(pContext != NULL);
1847         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1848
1849         ASSERT(pEvent != NULL);
1850
1851         if (params.size() < 1)
1852         {
1853                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1854                 return FALSE;
1855         }
1856
1857         if(!pEvent->m_pValue)
1858                 return FALSE;
1859         CFX_WideString& valEvent = pEvent->Value();
1860
1861         CFX_WideString wstrMask = params[0].operator CFX_WideString();
1862         if (wstrMask.IsEmpty()) return TRUE;
1863         
1864         std::wstring wstrValue(valEvent);
1865         
1866         if (pEvent->WillCommit())
1867         {
1868                 if (wstrValue.empty())
1869                         return TRUE;
1870                 int iIndexMask = 0;
1871                 for (std::wstring::iterator it = wstrValue.begin(); it != wstrValue.end(); it++)
1872                 {
1873                         wchar_t w_Value = *it;
1874             if (!maskSatisfied(w_Value,wstrMask[iIndexMask]))
1875                                 break;
1876                         iIndexMask++;
1877                 }
1878
1879                 if (iIndexMask != wstrMask.GetLength() || (iIndexMask != wstrValue.size() && wstrMask.GetLength() != 0))
1880                 {
1881                         Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE));
1882                         pEvent->Rc() = FALSE;
1883                 }
1884                 return TRUE;
1885         }
1886
1887         
1888         CFX_WideString &wideChange = pEvent->Change();
1889         std::wstring wChange(wideChange);
1890         
1891         if (wChange.empty())
1892                 return TRUE;
1893     int iIndexMask = pEvent->SelStart();
1894         //iIndexMask++;
1895         
1896         
1897         if (wstrValue.length() - (pEvent->SelEnd()-pEvent->SelStart()) + wChange.length() > (FX_DWORD)wstrMask.GetLength())
1898         {
1899                 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG));
1900                 pEvent->Rc() = FALSE;
1901                 return TRUE;
1902         }
1903         
1904         
1905         if (iIndexMask >= wstrMask.GetLength() && (!wChange.empty()))
1906         {
1907                 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG));
1908                 pEvent->Rc() = FALSE;
1909                 return TRUE;
1910         }
1911         
1912         for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++)
1913         {
1914                 if (iIndexMask >= wstrMask.GetLength())
1915                 {
1916                         Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG));
1917                         pEvent->Rc() = FALSE;
1918                         return TRUE;
1919                 }
1920                 wchar_t w_Mask = wstrMask[iIndexMask];
1921                 if (!isReservedMaskChar(w_Mask))
1922                 {
1923                         //wChange.insert(it,w_Mask);                            
1924                         *it = w_Mask;
1925                 }
1926                 wchar_t w_Change = *it;
1927                 
1928         if (!maskSatisfied(w_Change,w_Mask))
1929                 {
1930                         pEvent->Rc() = FALSE;
1931                         return TRUE;
1932                 }
1933                 iIndexMask++;
1934         }
1935         
1936         wideChange = wChange.c_str();   
1937         
1938         return TRUE;
1939 }
1940
1941
1942 //function AFSpecial_Keystroke(psf)
1943 FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(OBJ_METHOD_PARAMS)
1944 {
1945         v8::Isolate* isolate = ::GetIsolate(cc);
1946
1947         CJS_Context* pContext = (CJS_Context *)cc;
1948         ASSERT(pContext != NULL);
1949         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1950         ASSERT(pEvent != NULL);
1951
1952         if (params.size() != 1)
1953         {
1954                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1955                 return FALSE;
1956         }
1957
1958         std::string cFormat;
1959         int iIndex = (int)params[0];    
1960
1961         if(!pEvent->m_pValue)
1962                 return FALSE;
1963         //CJS_Value val = pEvent->Value();
1964         CFX_WideString& val = pEvent->Value();
1965         std::string strSrc = (FX_LPCSTR)CFX_ByteString::FromUnicode(val);
1966         std::wstring wstrChange(pEvent->Change());
1967         
1968         switch (iIndex) 
1969         {
1970         case 0:                         
1971                 cFormat = "99999";
1972                 break;
1973         case 1:                         
1974                 //cFormat = "99999-9999";
1975                 cFormat = "999999999";
1976                 break;
1977         case 2:                         
1978                 {
1979                         std::string NumberStr;
1980                         util::printx("9999999999", strSrc,NumberStr); 
1981                         if (strSrc.length() + wstrChange.length() > 7 )
1982                                 //cFormat = "(999) 999-9999";
1983                                 cFormat = "9999999999";
1984                         else 
1985                                 //cFormat = "999-9999";
1986                                 cFormat = "9999999";
1987                         break;
1988                 }
1989         case 3:
1990                 //cFormat = "999-99-9999";
1991                 cFormat = "999999999";
1992                 break;
1993         }
1994     
1995         CJS_Parameters params2;
1996         CJS_Value vMask(isolate, cFormat.c_str());
1997         params2.push_back(vMask);
1998         
1999     return AFSpecial_KeystrokeEx(cc,params2,vRet,sError);
2000 }
2001
2002 FX_BOOL CJS_PublicMethods::AFMergeChange(OBJ_METHOD_PARAMS)
2003 {
2004         CJS_Context* pContext = (CJS_Context *)cc;
2005         ASSERT(pContext != NULL);
2006         CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
2007         ASSERT(pEventHandler != NULL);
2008
2009         if (params.size() != 1)
2010         {
2011                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2012                 return FALSE;
2013         }
2014
2015         CFX_WideString swValue;
2016         if (pEventHandler->m_pValue != NULL)
2017                 swValue = pEventHandler->Value();
2018
2019         if (pEventHandler->WillCommit())
2020         {
2021                 vRet = swValue;
2022                 return TRUE;
2023         }
2024
2025         CFX_WideString prefix,postfix;
2026
2027         if (pEventHandler->SelStart() >= 0)
2028                 prefix = swValue.Mid(0,pEventHandler->SelStart());
2029         else
2030                 prefix = L"";
2031
2032
2033         if (pEventHandler->SelEnd() >= 0 && pEventHandler->SelEnd() <= swValue.GetLength())
2034                 postfix = swValue.Mid(pEventHandler->SelEnd(), swValue.GetLength() - pEventHandler->SelEnd());
2035         else postfix = L"";
2036
2037         vRet = prefix + pEventHandler->Change() + postfix;
2038
2039         return TRUE;
2040 }
2041
2042 FX_BOOL CJS_PublicMethods::AFParseDateEx(OBJ_METHOD_PARAMS)
2043 {
2044         CJS_Context* pContext = (CJS_Context *)cc;
2045         ASSERT(pContext != NULL);
2046
2047         if (params.size() != 2)
2048         {
2049                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2050                 return FALSE;
2051         }
2052
2053         CFX_WideString sValue = params[0].operator CFX_WideString();
2054         CFX_WideString sFormat = params[1].operator CFX_WideString();
2055
2056         FX_BOOL bWrongFormat = FALSE;
2057         double dDate = MakeRegularDate(sValue,sFormat,bWrongFormat);
2058
2059         if (JS_PortIsNan(dDate))
2060         {
2061                 CFX_WideString swMsg;
2062                 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE), (FX_LPCWSTR)sFormat);
2063                 Alert((CJS_Context *)cc, swMsg);
2064                 return FALSE;
2065         }
2066         
2067         vRet = dDate;
2068
2069         return TRUE;
2070 }
2071
2072 FX_BOOL CJS_PublicMethods::AFSimple(OBJ_METHOD_PARAMS)
2073 {
2074         if (params.size() != 3)
2075         {
2076                 CJS_Context* pContext = (CJS_Context *)cc;
2077                 ASSERT(pContext != NULL);
2078
2079                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2080                 return FALSE;
2081         }
2082
2083         vRet = (double)AF_Simple(params[0].operator CFX_WideString(), (double)params[1], (double)params[2]);
2084         return TRUE;
2085 }
2086
2087 FX_BOOL CJS_PublicMethods::AFMakeNumber(OBJ_METHOD_PARAMS)
2088 {
2089         if (params.size() != 1)
2090         {
2091                 CJS_Context* pContext = (CJS_Context *)cc;
2092                 ASSERT(pContext != NULL);
2093
2094                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2095                 return FALSE;
2096         }
2097     vRet = ParseStringToNumber(params[0].operator CFX_WideString());
2098         return TRUE;
2099 }
2100
2101 FX_BOOL CJS_PublicMethods::AFSimple_Calculate(OBJ_METHOD_PARAMS)
2102 {
2103         v8::Isolate* isolate = ::GetIsolate(cc);
2104
2105         CJS_Context* pContext = (CJS_Context *)cc;
2106         ASSERT(pContext != NULL);
2107
2108         if (params.size() != 2)
2109         {
2110                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2111                 return FALSE;
2112         }
2113
2114         CJS_Value params1 = params[1];
2115
2116         if (!params1.IsArrayObject() && params1.GetType() != VT_string)
2117         {
2118                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2119                 return FALSE;
2120         }
2121         
2122         CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
2123     ASSERT(pReaderDoc != NULL);
2124
2125         CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
2126         ASSERT(pReaderInterForm != NULL);
2127
2128         CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
2129         ASSERT(pInterForm != NULL);
2130
2131         double dValue;
2132         CFX_WideString sFunction = params[0].operator CFX_WideString();
2133         if (wcscmp(sFunction, L"PRD") == 0)
2134         dValue = 1.0;
2135         else
2136                 dValue = 0.0;
2137
2138         CJS_Array FieldNameArray = AF_MakeArrayFromList(isolate,params1);
2139
2140         int nFieldsCount = 0;
2141
2142         for (int i=0,isz=FieldNameArray.GetLength(); i<isz; i++)
2143         {
2144                 CJS_Value jsValue(isolate);
2145                 FieldNameArray.GetElement(i,jsValue);
2146         CFX_WideString wsFieldName = jsValue.operator CFX_WideString();
2147
2148         for (int j=0,jsz=pInterForm->CountFields(wsFieldName); j<jsz; j++)
2149                 {
2150                         if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName))
2151                         {
2152                                 double dTemp = 0.0;
2153
2154                                 switch (pFormField->GetFieldType())
2155                                 {
2156                                 case FIELDTYPE_TEXTFIELD:
2157                                 case FIELDTYPE_COMBOBOX:
2158                                         {
2159                                                 dTemp = ParseStringToNumber(pFormField->GetValue());
2160                                                 break;
2161                                         }
2162                                 case FIELDTYPE_PUSHBUTTON:
2163                                         {
2164                                                 dTemp = 0.0;
2165                                                 break;
2166                                         }
2167                                 case FIELDTYPE_CHECKBOX:
2168                                 case FIELDTYPE_RADIOBUTTON:
2169                                         {
2170                                                 dTemp = 0.0;
2171                                                 for (int c=0,csz=pFormField->CountControls(); c<csz; c++)
2172                                                 {
2173                                                         if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c))
2174                                                         {
2175                                                                 if (pFormCtrl->IsChecked())
2176                                                                 {
2177                                                                         dTemp += ParseStringToNumber(pFormCtrl->GetExportValue());
2178                                                                         break;
2179                                                                 }
2180                                                                 else
2181                                                                         continue;
2182                                                         }
2183                                                 }
2184                                                 break;
2185                                         }
2186                                 case FIELDTYPE_LISTBOX:
2187                                         {
2188                                                 dTemp = 0.0;
2189                                                 if (pFormField->CountSelectedItems() > 1)
2190                                                         break;
2191                                                 else
2192                                                 {
2193                                                         dTemp = ParseStringToNumber(pFormField->GetValue());
2194                                                         break;
2195                                                 }
2196                                         }
2197                                 default:
2198                                         break;
2199                                 }
2200
2201                                 if (i == 0 && j == 0 && (wcscmp(sFunction,L"MIN") == 0 || wcscmp(sFunction, L"MAX") == 0))
2202                                         dValue = dTemp;
2203
2204                                 dValue = AF_Simple(sFunction, dValue, dTemp);
2205
2206                                 nFieldsCount++;
2207                         }
2208                 }
2209         }
2210
2211         if (wcscmp(sFunction, L"AVG") == 0 && nFieldsCount > 0)
2212                 dValue /= nFieldsCount;
2213
2214         dValue = (double)floor(dValue * FXSYS_pow((double)10,(double)6) + 0.49) / FXSYS_pow((double)10,(double)6);
2215         CJS_Value jsValue(isolate,dValue);
2216         if((CJS_EventHandler*)pContext->GetEventHandler()->m_pValue)
2217                 ((CJS_EventHandler*)pContext->GetEventHandler())->Value() = jsValue;
2218
2219         return TRUE;
2220 }
2221
2222 /* This function validates the current event to ensure that its value is 
2223 ** within the specified range. */
2224
2225 FX_BOOL CJS_PublicMethods::AFRange_Validate(OBJ_METHOD_PARAMS)
2226 {
2227         CJS_Context* pContext = (CJS_Context *)cc;
2228         ASSERT(pContext != NULL);
2229         CJS_EventHandler* pEvent = pContext->GetEventHandler();
2230         ASSERT(pEvent != NULL);
2231
2232         if (params.size() != 4) 
2233         {
2234                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2235                 return FALSE;
2236         }
2237
2238         if(!pEvent->m_pValue)
2239                 return FALSE;
2240         if (pEvent->Value().IsEmpty() )
2241                 return TRUE;
2242         double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2243         FX_BOOL bGreaterThan, bLessThan;
2244         double  dGreaterThan, dLessThan;
2245     bGreaterThan = (FX_BOOL)params[0];
2246         CFX_WideString swMsg;
2247         dGreaterThan = (double)params[1];
2248         bLessThan = (FX_BOOL)params[2];
2249         dLessThan = (double)params[3];
2250
2251         if (bGreaterThan && bLessThan)
2252         {
2253                 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2254                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1),(FX_LPCWSTR)params[1].operator CFX_WideString(), (FX_LPCWSTR)params[3].operator CFX_WideString());
2255         }
2256         else if (bGreaterThan)
2257         {
2258                 if (dEentValue < dGreaterThan)
2259                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2), (FX_LPCWSTR)params[1].operator CFX_WideString());
2260         }
2261         else if (bLessThan)
2262         {
2263                 if (dEentValue > dLessThan)
2264                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3), (FX_LPCWSTR)params[3].operator CFX_WideString());
2265         }
2266
2267         if (!swMsg.IsEmpty())
2268         {
2269                 Alert(pContext, swMsg);
2270                 pEvent->Rc() = FALSE;
2271         }
2272         return TRUE;
2273 }
2274
2275 FX_BOOL CJS_PublicMethods::AFExtractNums(OBJ_METHOD_PARAMS)
2276 {
2277         v8::Isolate* isolate = ::GetIsolate(cc);
2278         CJS_Context* pContext = (CJS_Context*)cc;
2279         ASSERT(pContext != NULL);
2280
2281         if (params.size() != 1) 
2282         {
2283                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2284                 return FALSE;
2285         }
2286
2287         CJS_Array nums(isolate);
2288
2289         CFX_WideString str = params[0].operator CFX_WideString();
2290         CFX_WideString sPart;
2291
2292         if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2293                 str = L"0" + str;
2294
2295         int nIndex = 0;
2296         for (int i=0, sz=str.GetLength(); i<sz; i++)
2297         {
2298                 FX_WCHAR wc = str.GetAt(i);
2299                 if (IsDigit((wchar_t)wc))
2300                 {
2301                         sPart += wc;
2302                 }
2303                 else
2304                 {
2305                         if (sPart.GetLength() > 0)
2306                         {
2307                                 nums.SetElement(nIndex,CJS_Value(isolate,(FX_LPCWSTR)sPart));
2308                                 sPart = L"";
2309                                 nIndex ++;
2310                         }
2311                 }
2312         }
2313
2314         if (sPart.GetLength() > 0)
2315         {
2316                 nums.SetElement(nIndex,CJS_Value(isolate,(FX_LPCWSTR)sPart));   
2317         }
2318
2319         if (nums.GetLength() > 0)
2320                 vRet = nums;
2321         else
2322                 vRet.SetNull();
2323
2324         return TRUE;
2325 }