apply FSL(Flora Software License)
[apps/home/calculator.git] / src / calculator_edje.c
1 /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   * 
4   * Licensed under the Flora License, Version 1.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   * 
8   *     http://www.tizenopensource.org/license
9   * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17
18
19 #include <stdbool.h>            /*  true/false */
20 #include <Elementary.h>
21 #include <dlog.h>
22
23 #include "calc-main.h"
24 #include "calculator_parser.h"
25 #include "calc-string.h"
26 #include "calc-expression.h"
27 #include "calc-view.h"
28 #include <svi.h>
29
30 #define CALCULATOR_CHAR_IS_OPERATOR(C) ((C == '+')||(C == '-')||(C == 'x')||(C == '/')) /**<judge if a char is a basic operator*/
31 #define CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(C) ((C == 'x')||(C == '/'))                    /**<judge if an operator is "*" or "/"*/
32 #define CALCULATOR_CHAR_IS_PLUS_DEDUCT(C) ((C == '+')||(C == '-'))
33 #define CALCULATOR_CHAR_IS_DIGITAL(C)(C >= '0' && C <= '9')
34 #define CALCULATOR_IS_DIGIT_DOT(ch, decimal) (isdigit(ch) || decimal == (ch))
35
36 static Elm_Entry_Filter_Limit_Size limit_filter_data;
37
38 extern int get_max_fontsize();
39 extern void _calc_view_show_newest_histroy(Evas_Object * entry);
40 extern void _calc_view_clear_histroy(Evas_Object * entry);
41 extern gboolean __calculator_search_function(char *op, int* len);
42 static void __calculator_wrong_format_create(char * wrong_string);
43 extern gboolean __calculator_search_function(char *op, int* len);
44
45 static struct appdata *ad;      /* will be removed */
46 static calculator_state_t calculator_state = CALCULATOR_WAITING_INPUT;
47 static double last_result = 0.0;
48
49 int calculator_cursor_pos = 0;
50 char calculator_input_str[MAX_EXPRESSION_LENGTH] = { 0 };
51 char calculator_before_paste_str[MAX_EXPRESSION_LENGTH] = { 0 };
52
53 bool paste_flag = FALSE;
54
55 struct lconv *locale = NULL;
56 char *decimal = NULL;
57 char *separator = NULL;
58 char decimal_ch = 0;
59 char separator_ch = 0;
60
61 static op_item_t calc_op_item[] = {
62         {OP_INVALID, "", NULL},
63
64         /* basic */
65         {OP_PARENTHESIS, "()", NULL},
66         {OP_DELETE, "<-", NULL},
67         {OP_CLEAR, "C", NULL},
68         {OP_DIVIDE, "/", NULL},
69
70         {OP_NUM_7, "7", NULL},
71         {OP_NUM_8, "8", NULL},
72         {OP_NUM_9, "9", NULL},
73         {OP_MULTIPLY, "x", NULL},
74
75         {OP_NUM_4, "4", NULL},
76         {OP_NUM_5, "5", NULL},
77         {OP_NUM_6, "6", NULL},
78         {OP_MINUS, "-", NULL},
79
80         {OP_NUM_1, "1", NULL},
81         {OP_NUM_2, "2", NULL},
82         {OP_NUM_3, "3", NULL},
83         {OP_PLUS, "+", NULL},
84
85         {OP_DOT, ".", NULL},
86         {OP_NUM_0, "0", NULL},
87         {OP_PLUS_MINUS, "+/-", NULL},
88         {OP_EQUAL, "=", NULL},
89
90         /* functional */
91         {OP_PERCENT, "%", NULL},
92         {OP_ROOT, "sqrt", "sqrt("},
93         {OP_FACT, "x!", "!"},
94
95         {OP_SIN, "sin", "sin("},
96         {OP_COS, "cos", "cos("},
97         {OP_TAN, "tan", "tan("},
98
99         {OP_LN, "ln", "ln("},
100         {OP_LOG, "log", "log("},
101         {OP_1X, "1/x", "1/x"},
102
103         {OP_EX, "e^x", "e^("},
104         {OP_X2, "x^2", "^2"},
105         {OP_XY, "x^y", "^("},
106
107         {OP_ABS, "abs", "abs("},
108         {OP_PI, "Pi", "p"},
109         {OP_E, "e", "e"},
110 };
111 char *error_string[] = {
112     "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE",
113     "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE",
114     "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE",
115     "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO",
116     "IDS_CCL_POP_NO_NUMBER_ERROR",
117     "IDS_CCL_POP_ERROR",
118     "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR",
119     "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION",
120     "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION",
121     "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION",
122     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION",
123     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION",
124     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION",
125     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION",
126     "IDS_CCL_POP_NO_OPERATOR_ERROR",
127     "IDS_CCL_POP_SYNTAX_ERROR",
128 };
129
130
131 calculator_state_t calculator_get_state()
132 {
133         return calculator_state;
134 }
135
136 void _calc_add_tag(char *string, char *format_string)
137 {
138         CONV_FUNC_IN();
139         int i = 0;
140         int begin = 0;
141         int end = 0;
142         char buf[MAX_EXPRESSION_LENGTH] = { 0 };
143         char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
144         char *p = NULL;
145         while (string[i] != '\0') {
146                 if (CALCULATOR_CHAR_IS_DIGITAL(string[i])
147                     || string[i] == separator_ch || string[i] == decimal_ch) {
148                         begin = i;
149                         p = &string[begin];
150                         while (CALCULATOR_CHAR_IS_DIGITAL(string[i])
151                                || string[i] == separator_ch
152                                || string[i] == decimal_ch) {
153                                 i++;
154                         }
155                         end = i - 1;
156                         strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
157                         tmp[end - begin + 1] = '\0';
158                         memset(buf, 0, sizeof(buf));
159                         snprintf(buf, sizeof(buf),
160                                  "<align=right><+ font_size=%d><color=#000000ff>%s",
161                                  get_max_fontsize(), tmp);
162                         strcat(format_string, buf);
163                 } else {
164                         begin = i;
165                         p = &string[begin];
166                         while (!CALCULATOR_CHAR_IS_DIGITAL(string[i])
167                                && string[i] != separator_ch
168                                && string[i] != decimal_ch
169                                && string[i] != '\0') {
170                                 i++;
171                         }
172                         end = i - 1;
173                         strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
174                         tmp[end - begin + 1] = '\0';
175                         memset(buf, 0, sizeof(buf));
176                         snprintf(buf, sizeof(buf),
177                                  "<align=right><+ font_size=%d><color=#855B11FF>%s",
178                                  get_max_fontsize(), tmp);
179                         strcat(format_string, buf);
180                 }
181
182         }
183         PLOG("Expression with tag : %s\n", format_string);
184         CONV_FUNC_OUT();
185 }
186
187 /* BEGIN INPUT ENTRY RELATED */
188
189 /**
190 * @describe
191 *
192 *
193 * @param    entry
194 * @param    str
195 * @return    void
196 * @exception
197 */
198 static void _calc_entry_text_set(Evas_Object * entry, const char *str)
199 {
200         CONV_FUNC_IN();
201         char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
202         char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
203
204         if (str == NULL) {
205                 return;
206         }
207
208         if (strlen(str) == 0) {
209                 elm_entry_entry_set(entry, "");
210                 calc_view_cursor_set_position(entry, calculator_cursor_pos);
211                 return;
212         }
213         calc_expr_format_expression(str, tmp);
214         _calc_add_tag(tmp, tag_text);
215         elm_entry_entry_set(entry, tag_text);
216
217         calc_view_cursor_set_position(entry, calculator_cursor_pos);
218         calc_view_revise_input_scroller(ad);
219         CONV_FUNC_OUT();
220
221 }
222
223 void _calc_entry_text_set_rotate(struct appdata *ad)
224 {
225         if (calculator_state == CALCULATOR_CALCULATED) {
226                 _calc_view_show_newest_histroy(ad->input_entry);
227                 elm_entry_cursor_end_set(ad->input_entry);
228         } else {
229                 _calc_entry_text_set(ad->input_entry, calculator_input_str);
230         }
231 }
232
233 /**
234 * @describe
235 *
236 *
237 * @param    entry
238 * @param    str
239 * @return    void
240 * @exception
241 */
242 static void _calc_entry_text_insert(Evas_Object * entry, char *str)
243 {
244         CONV_FUNC_IN();
245         calc_expr_input_insert(calculator_input_str, &calculator_cursor_pos,
246                                str);
247         printf("calculator_input_str=%s, str=%s, calculator_cursor_pos=%d\n", calculator_input_str, str, calculator_cursor_pos);
248         _calc_entry_text_set(entry, calculator_input_str);
249         CONV_FUNC_OUT();
250 }
251
252 /**
253 * @describe
254 *
255 *
256 * @param    entry
257 * @param    from_pos
258 * @param    end_pos
259 * @return    void
260 * @exception
261 */
262 static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
263                                     const int end_pos)
264 {
265         CONV_FUNC_IN();
266         string_remove_at(calculator_input_str, from_pos,
267                          end_pos - from_pos + 1);
268         calculator_cursor_pos = from_pos;
269         _calc_entry_text_set(entry, calculator_input_str);
270         CONV_FUNC_OUT();
271 }
272
273 /**
274 * @describe
275 *       Set correct cursor position in entry.
276 *
277 * @param    entry
278 * @return    void
279 * @exception
280 */
281 static void _calc_entry_cursor_set(Evas_Object * entry)
282 {
283         CONV_FUNC_IN();
284         calc_view_cursor_set_position(entry, calculator_cursor_pos);
285         CONV_FUNC_OUT();
286 }
287
288 /**
289 * @describe
290 *
291 *
292 * @param    entry
293 * @return    void
294 * @exception
295 */
296 static void _calc_entry_backspace(Evas_Object * entry)
297 {
298         CONV_FUNC_IN();
299         calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
300         _calc_entry_text_set(entry, calculator_input_str);
301         CONV_FUNC_OUT();
302 }
303
304 /**
305 * @describe
306 *
307 *
308 * @param    entry
309 * @return    void
310 * @exception
311 */
312 void _calc_entry_clear(Evas_Object * entry)
313 {
314         memset(calculator_input_str, 0, sizeof(calculator_input_str));
315         calculator_cursor_pos = 0;
316         _calc_entry_text_set(entry, "");
317         calc_view_cursor_set_position(entry, calculator_cursor_pos);
318 }
319
320 /* END INPUT ENTRY RELATED */
321
322 /**
323 * @describe
324 *
325 *
326 * @param    text
327 * @param    begin
328 * @param    end
329 * @return    void
330 * @exception
331 */
332 static bool
333 __calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
334                                               int *begin, int *end)
335 {
336         CONV_FUNC_IN();
337
338         int pos = cur_pos - 1;
339         if (pos < 0) {
340                 pos++;
341                 pos = 0;
342         }
343         int _begin = 0;
344         int _end = 0;
345
346         if ('p' == text[pos] || 'e' == text[pos]) {
347                 *begin = pos;
348                 *end = pos;
349                 return true;
350         } else if (CALCULATOR_IS_DIGIT_DOT(text[pos], decimal_ch)) {
351                 for (_begin = pos - 1;
352                      CALCULATOR_IS_DIGIT_DOT(text[_begin], decimal_ch)
353                      && _begin >= 0; --_begin) {
354                         ;       /* NULL */
355                 }
356                 _begin++;
357                 if (_begin > 1 && '-' == text[_begin - 1]
358                     && '(' == text[_begin - 2]) {
359                         _begin--;
360                 }
361                 for (_end = pos + 1;
362                      CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
363                      && _end < strlen(text); ++_end) {
364                         ;       /* NULL */
365                 }
366                 _end--;
367
368                 *begin = _begin;
369                 *end = _end;
370                 return true;
371         } else {
372                 return false;
373         }
374         CONV_FUNC_OUT();
375 }
376
377 /**
378 * @describe
379 *
380 *
381 * @param    entry_text
382 * @param    str
383 * @param    from
384 * @param    end
385 * @return    void
386 * @exception
387 */
388 static bool
389 __calculator_get_cursor_position_float_string(char *entry_text, char *str,
390                                               int cur_pos, int *from, int *end)
391 {
392         CONV_FUNC_IN();
393
394         int from_pos = cur_pos;
395         int end_pos = cur_pos;
396
397         if (false ==
398             __calculator_get_float_num_in_cursor_position(entry_text, cur_pos,
399                                                           &from_pos,
400                                                           &end_pos)) {
401                 return false;
402         }
403
404         /* set from&end position */
405         if (from != NULL) {
406                 *from = from_pos;
407         }
408         if (end != NULL) {
409                 *end = end_pos;
410         }
411
412         strncpy(str, entry_text + from_pos, end_pos - from_pos + 1);
413         str[end_pos - from_pos + 1] = '\0';
414         CONV_FUNC_OUT();
415         return true;
416 }
417
418 /**
419 * @describe
420 *   Get the float number in current cursor
421 *
422 * @param    entry_text
423 * @param    str
424 * @return    void
425 * @exception
426 */
427 static bool
428 __calculator_get_before_cursor_float_string(char *entry_text, char *str)
429 {
430         CONV_FUNC_IN();
431
432         int from_pos = calculator_cursor_pos;
433         int end_pos = calculator_cursor_pos;
434
435         if (false ==
436             __calculator_get_float_num_in_cursor_position(entry_text,
437                                                           calculator_cursor_pos,
438                                                           &from_pos,
439                                                           &end_pos)) {
440                 return false;
441         }
442         snprintf(str, calculator_cursor_pos - from_pos + 1, "%s",
443                  entry_text + from_pos);
444         CONV_FUNC_OUT();
445         return true;
446 }
447
448 /**
449 * @describe
450 *   Get string before cursor in the Entry.
451 *
452 * @param    entry_text
453 * @param    str
454 * @return    void
455 * @exception
456 */
457 static void
458 __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
459 {
460         CONV_FUNC_IN();
461
462         if (calculator_cursor_pos > 0) {
463                 strncpy(str, entry_text, calculator_cursor_pos);
464                 str[calculator_cursor_pos] = '\0';
465         } else {
466                 strcpy(str, "");
467         }
468         CONV_FUNC_OUT();
469 }
470
471 /**
472 * @describe
473 *
474 * judge the type of current input
475 *
476 * @param    input
477 * @return    void
478 * @exception
479 */
480 static last_char_t __calculator_string_get_char_type( char ch_in)
481 {
482         CONV_FUNC_IN();
483         if (ch_in == '\0') {
484                 return CHAR_IS_NULL;
485         }
486         if (ch_in == 'p') {
487                 return CHAR_IS_PI;
488         }
489         if (ch_in == 'e') {
490                 return CHAR_IS_E;
491         }
492         if (CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(ch_in)) {
493                 return CHAR_IS_MULTIPLY_DIVIDE;
494         }
495         if (ch_in == '(') {
496                 return CHAR_IS_LEFT_PARENTHESE;
497         }
498         if (ch_in == ')') {
499                 return CHAR_IS_RIGHT_PARENTHESE;
500         }
501         if (CALCULATOR_CHAR_IS_DIGITAL(ch_in)) {
502                 return CHAR_IS_DIGIT;
503         }
504         if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(ch_in) ){
505                 return CHAR_IS_PLUS_MINUS;
506         }
507         if (ch_in == decimal_ch) {
508                 return CHAR_IS_POINT;
509         }
510         return CHAR_IS_CHARACTER;
511         CONV_FUNC_OUT();
512 }
513
514 static bool  __calculator_string_digit_in(const char *input)
515 {
516         int i =0;
517         while(input[i]!='\0'){
518                 if(CALCULATOR_CHAR_IS_DIGITAL(input[i])){
519                         return TRUE;
520                 }else{
521                         i++;
522                 }
523         }
524          return FALSE;
525 }
526
527 /*
528 * search charactor in input string, if have charactor, return True and index of first charactor;
529 * else return False;
530 */
531 static bool __calculator_string_char_search(const char *input, int *index)
532 {
533         CONV_FUNC_IN();
534         int len_cp = strlen(input);
535         if(len_cp <= 0){
536                 return FALSE;
537         }
538         int i = 0;
539         for(; i < len_cp ; i++){
540                 last_char_t cur_char_type = __calculator_string_get_char_type(input[i]);
541                 if (CHAR_IS_CHARACTER == cur_char_type) {
542                         *index  = i;
543                         return TRUE;
544                 }
545         }
546         return FALSE;
547         CONV_FUNC_OUT();
548 }
549
550 /*
551 * search invalid charactor in input string, if have invalid charactor, return True and index of first invalid charactor;
552 * else return False;
553 */
554 static bool __calculator_string_invalid_char_search(char *input, int *index)
555 {
556         int sub_index = 0;
557         char *p = input;
558         bool char_in = FALSE;
559         int len = 0;
560         char_in = __calculator_string_char_search(p, &sub_index);
561         if(!char_in){/*no charactor*/
562                 return FALSE;
563         }
564         while(p){
565                 /* charactor  present*/
566                 *index += sub_index;
567                 p += sub_index;
568                 if(!__calculator_search_function(p, &len)){/*charactor not a function*/
569                 return TRUE;
570                 }else{/*the first sevaral charactors are function, continue search*/
571                         *index += len;
572                         p += len;
573                 }
574         }
575         return FALSE;
576 }
577 /**
578 * @describe
579 *
580 *
581 * @param    entry
582 * @param    op_item
583 * @return    void
584 * @exception
585 */
586 static void
587 __calculator_control_panel_number_button_clicked(Evas_Object * entry,
588                                                  op_item_t * op_item)
589 {
590         CONV_FUNC_IN();
591
592         /* replace special characters */
593         char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
594         snprintf(entry_text, sizeof(entry_text), "%s", calculator_input_str);
595
596         //Current state is calculated, clear all
597         if (calculator_state == CALCULATOR_CALCULATED) {
598                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
599                 _calc_entry_clear(entry);
600                 _calc_entry_text_insert(entry, op_item->op_sym);
601                 calculator_state = CALCULATOR_OPERAND_INPUT;
602                 return;
603         }
604
605         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
606         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
607         int before_len = 0;
608         int nDigitCnt = 0;
609         int nPointCnt = 0;
610         __calculator_get_cursor_position_float_string(entry_text, str_buf,
611                                                       calculator_cursor_pos,
612                                                       NULL, NULL);
613         __calculator_get_input_from_begin_to_cursor(entry_text, before_cursor);
614         before_len = strlen(before_cursor);
615         calculator_get_digits_number(str_buf, &nDigitCnt, &nPointCnt);
616
617         char str_bufa[MAX_EXPRESSION_LENGTH] = { 0 };
618         __calculator_get_before_cursor_float_string(entry_text, str_bufa);
619         if (strcmp(str_bufa, "0") == 0) {
620                 _calc_entry_backspace(entry);
621         }
622
623         if (strlen(str_buf) >= MAX_NUM_LENGTH) {
624                 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
625                 return;
626         } else if (nPointCnt >= MAX_DECIMAL_NUM
627                    && calculator_cursor_pos > nDigitCnt) {
628                 __calculator_wrong_format_create(CALC_MSG_MAX_DEC_DIGIT);
629                 return;
630         } else if (before_len > 0
631                    && (__calculator_string_get_char_type(before_cursor[before_len - 1]) ==
632                    CHAR_IS_PI
633                    || __calculator_string_get_char_type(before_cursor[before_len - 1]) ==
634                    CHAR_IS_E)) {
635                 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
636                 return;
637         } else if (before_len > 0
638                    && ((before_cursor[before_len - 1] == '(')
639                        ||
640                        CALCULATOR_CHAR_IS_DIGITAL(before_cursor[before_len - 1])
641                        || CALCULATOR_CHAR_IS_OPERATOR(before_cursor[before_len - 1]) || (int)before_cursor[before_len - 1] > 120))      //* or/
642         {
643                 _calc_entry_text_insert(entry, op_item->op_sym);
644                 calculator_state = CALCULATOR_OPERAND_INPUT;
645                 return;
646         } else if (before_len > 0 && (before_cursor[before_len - 1] == ')')) {
647                 _calc_entry_text_insert(entry, op_item->op_sym);
648                 return;
649         } else {
650                 _calc_entry_text_insert(entry, op_item->op_sym);
651                 calculator_state = CALCULATOR_OPERAND_INPUT;
652                 return;
653         }
654         CONV_FUNC_OUT();
655 }
656
657 /**
658 * @describe
659 *
660 *
661 * @param    entry
662 * @return    void
663 * @exception
664 */
665 static void _calc_btn_dot_clicked(Evas_Object * entry)
666 {
667         CONV_FUNC_IN();
668         char temp[MAX_RESULT_LENGTH] = { 0 };
669         char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
670         int str_num_len = 0;
671
672         char decimal_str[32] = { 0 };
673
674         /* replace special characters */
675         char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
676         strncpy(entry_text, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
677
678         if (calculator_state == CALCULATOR_CALCULATED) {
679                 calc_expr_num_format_result(last_result, temp);
680                 if (strchr(temp, 'E') != NULL) {
681                         return;
682                 }
683                 /* science number */
684                 _calc_entry_clear(entry);
685                 _calc_entry_text_insert(entry, temp);
686         }
687
688         int from_pos = 0;
689         int end_pos = 0;
690         if (!__calculator_get_cursor_position_float_string
691             (entry_text, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
692                 if (calculator_cursor_pos == 0
693                     || IS_OPERATOER(calculator_input_str[from_pos - 1])) {
694                         snprintf(decimal_str, sizeof(decimal_str), "0%c",
695                                  decimal_ch);
696                         _calc_entry_text_insert(entry, decimal_str);
697                         calculator_state = CALCULATOR_OPERAND_INPUT;
698                         return;
699                 } else {
700                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
701                 }
702                 return;
703         } else {
704                 if (strcmp(str_num, "p") == 0 || strcmp(str_num, "e") == 0) {
705                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
706                         return;
707                 }
708         }
709
710         str_num_len = strlen(str_num);
711         if (str_num_len > 0 && str_num[str_num_len - 1] == decimal_ch) {
712                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
713                 return;
714         }
715
716         int nDigitCnt = 0;
717         int nPointCnt = 0;
718         calculator_get_digits_number(str_num, &nDigitCnt, &nPointCnt);
719
720         if (nDigitCnt >= 15) {
721                 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
722                 return;
723         }
724
725         if (nPointCnt > 0) {
726                 __calculator_wrong_format_create(CALC_MSG_ENTRY_LIMIT);
727                 return;
728         }
729         snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
730         _calc_entry_text_insert(entry, decimal_str);
731         calculator_state = CALCULATOR_OPERAND_INPUT;
732         CONV_FUNC_OUT();
733         return;
734 }
735
736 /**
737 * @describe
738 *
739 *
740 * @param        entry
741 * @return       void
742 * @exception
743 */
744 static void _calc_btn_backspace_clicked(Evas_Object * entry)
745 {
746         CONV_FUNC_IN();
747
748         if (calculator_state == CALCULATOR_CALCULATED) {
749                 calculator_state = CALCULATOR_OPERATOR_INPUT;
750                 if (calculator_cursor_pos > strlen(calculator_input_str)) {
751                         calculator_cursor_pos = strlen(calculator_input_str);   /* set last position */
752                 }
753         }
754         _calc_entry_backspace(entry);
755         CONV_FUNC_OUT();
756 }
757
758 static int __calculator_delete_long_press(void *data)
759 {
760         CONV_FUNC_IN();
761         Evas_Object *entry = (Evas_Object *) data;
762         _calc_btn_backspace_clicked(entry);
763         CONV_FUNC_OUT();
764         return 1;
765 }
766
767 /**
768 * @describe
769 *   Process +.-.*.\ these four buttons clicked.
770 *
771 * @param        entry
772 * @param        op_item
773 * @return       void
774 * @exception
775 */
776 static void
777 __calculator_control_normal_func_clicked(Evas_Object * entry,
778                                          op_item_t * op_item)
779 {
780         CONV_FUNC_IN();
781         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
782         strncpy(all_input, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
783
784         if (calculator_state == CALCULATOR_CALCULATED) {
785                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
786                 char temp[20] = { 0 };
787
788                 calc_expr_num_format_result(last_result, temp);
789                 _calc_entry_clear(entry);
790
791                 if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or sicience number
792                 {
793                         _calc_entry_text_insert(entry, "(");
794                         _calc_entry_text_insert(entry, temp);
795                         _calc_entry_text_insert(entry, ")");
796                 } else {
797                         _calc_entry_text_insert(entry, temp);
798                 }
799
800                 _calc_entry_text_insert(entry, op_item->op_sym);
801                 calculator_state = CALCULATOR_OPERATOR_INPUT;
802                 return;
803
804         }
805     if(!strcmp(op_item->op_sym, "x") || !strcmp(op_item->op_sym, "/") || !strcmp(op_item->op_sym, "+")){
806                 if(!__calculator_string_digit_in(calculator_input_str)){ return; }
807         }
808         int nCntOp = calc_expr_get_operator_num(all_input);
809         if (nCntOp >= MAX_OPERATOR_NUM) {       /* Can't exceed 20 operators */
810                 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
811                 return;
812         }
813
814         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
815         int input_len = 0;
816
817         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
818         input_len = strlen(before_cursor);
819
820         if (input_len > 0) {
821                 if (before_cursor[input_len - 1] == '('
822                     && !strcmp(op_item->op_sym, "-")) {
823                         _calc_entry_text_insert(entry, op_item->op_sym);
824                         calculator_state = CALCULATOR_OPERATOR_INPUT;
825                 } else if (((input_len > 1) && (before_cursor[input_len - 1] == '-') && (before_cursor[input_len - 2] == '('))  //(-
826                            || before_cursor[input_len - 1] == decimal_ch || before_cursor[input_len - 1] == '(')        // . or (
827                 {
828
829                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
830                         return;
831                 } else if (IS_OPERATOER(before_cursor[input_len - 1])) {
832                         if ((input_len > 1 || !strcmp(op_item->op_sym, "-"))
833                             || input_len == 1) {
834                                 _calc_entry_backspace(entry);
835                                 _calc_entry_text_insert(entry, op_item->op_sym);
836                                 calculator_state = CALCULATOR_OPERATOR_INPUT;
837                         } else {
838                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
839                         }
840                         return;
841                 } else if (before_cursor[input_len - 1] == ')') //
842                 {
843                         _calc_entry_text_insert(entry, op_item->op_sym);
844                         calculator_state = CALCULATOR_OPERATOR_INPUT;
845                         return;
846                 } else {
847                         if (!IS_DIGITAL(before_cursor[input_len - 1])) {
848                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
849                                 return;
850                         } else {
851                                 _calc_entry_text_insert(entry, op_item->op_sym);
852                                 calculator_state = CALCULATOR_OPERATOR_INPUT;
853                                 return;
854                         }
855                 }
856         } else {                /* before_cursor si empty */
857
858                 _calc_entry_text_insert(entry, op_item->op_sym);
859                 calculator_state = CALCULATOR_OPERATOR_INPUT;
860         }
861         CONV_FUNC_OUT();
862 }
863
864 /**
865 * @describe
866 *
867 *
868 * @param    entry
869 * @return    void
870 * @exception
871 */
872 static void __calculator_symbol_negative_clicked(Evas_Object * entry)
873 {
874         CONV_FUNC_IN();
875
876         char result[MAX_RESULT_LENGTH] = { 0 };
877
878         if (calculator_state == CALCULATOR_CALCULATED) {
879                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
880
881                 calc_expr_num_format_result(last_result, result);
882                 if (last_result < 0) {
883                         string_remove_at(result, 0, 1); //remove '-'
884                 } else {
885                         string_insert(result, 0, "(-"); // add (-xxx)
886                         string_insert(result, strlen(result), ")");
887                 }
888
889                 _calc_entry_clear(entry);
890                 _calc_entry_text_insert(entry, result);
891
892                 calculator_state = CALCULATOR_OPERAND_INPUT;
893                 //use_last_result = 1;
894
895                 return;
896         }
897
898         int cursor = calculator_cursor_pos;
899         int begin = 0, length = 0;
900         char expr[MAX_EXPRESSION_LENGTH] = { 0 };
901         strncpy(expr, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
902         int flag = 0;
903
904         cursor -= 1;
905         if (expr[cursor] == ')') {
906                 cursor -= 1;
907                 flag = 1;       /* before current cursor is ')' */
908         }
909
910         if (0 ==
911             calc_expr_get_current_num_at_cursor(expr, cursor, &begin,
912                                                 &length)) {
913                 if (expr[begin] == '-') {
914                         if (begin > 0 && expr[begin - 1] == '('
915                             && expr[begin + length] == ')') {
916                                 string_remove_at(expr, begin + length, 1);      //remove ')'
917                                 string_remove_at(expr, begin - 1, 2);   // remove '(-'
918                                 calculator_cursor_pos -= flag ? 3 : 2;
919                         } else {
920                                 string_remove_at(expr, begin, 1);
921                                 calculator_cursor_pos -= 1;
922                         }
923
924                 } else {
925                         if (flag == 1)  //not '(-xxx)' but has ')'
926                         {
927                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
928                                 return;
929                         } else {
930                                 string_insert(expr, begin + length, ")");
931                                 string_insert(expr, begin, "(-");
932                                 calculator_cursor_pos +=
933                                     (((begin + length) ==
934                                       calculator_cursor_pos) ? 3 : 2);
935                         }
936                 }
937                 strncpy(calculator_input_str, expr, MAX_EXPRESSION_LENGTH - 1);
938
939                 _calc_entry_text_set(entry, calculator_input_str);
940                 _calc_entry_cursor_set(entry);
941
942                 calculator_state = CALCULATOR_OPERAND_INPUT;
943
944         } else {
945                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
946         }
947         CONV_FUNC_OUT();
948 }
949
950 /* search the previous operator and value */
951 static char * __calculator_search_prev_input(char *input_str)
952 {
953         int i = strlen(input_str) - 1;
954         int rightbracket = 0;   
955         char *prev_input = NULL;
956         for ( ; i > 0; i--){
957                 if (input_str[i] == ')') {
958                         rightbracket++;
959                 } else if (input_str[i] == '(') {               
960                         rightbracket--;
961                 }
962                 if ((CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
963                         ||CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) && (rightbracket == 0)){
964                         prev_input = &input_str[i];                     
965                         return prev_input;
966                 }
967         }
968         return prev_input;
969 }
970
971 /**
972 * @describe
973 *
974 *
975 * @param        entry
976 * @return       void
977 * @exception
978 */
979 static void __calculator_op_equal(Evas_Object * entry)
980 {
981         CONV_FUNC_IN();
982         if (calculator_state == CALCULATOR_CALCULATED) {
983                 /*duplicate previous input operator and value*/
984                 char *p = __calculator_search_prev_input(calculator_input_str);
985                 if (p == NULL) {
986                         return;
987                 }
988                 char prev_input[32] = { 0 };
989                 int len = g_strlcpy(prev_input, p, sizeof(prev_input));
990                 if(len >= sizeof(prev_input)){
991                         return;
992                 }
993                 char temp[32] = { 0 };
994                 calc_expr_num_format_result(last_result, temp);
995                 _calc_entry_clear(entry);
996
997                 if (temp[0] == '-' || strchr(temp, 'E')) {
998                         _calc_entry_text_insert(entry, "(");
999                         _calc_entry_text_insert(entry, temp);
1000                         _calc_entry_text_insert(entry, ")");
1001                 } else {
1002                         _calc_entry_text_insert(entry, temp);
1003                 }
1004                 _calc_entry_text_insert(entry, prev_input);
1005                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1006         }
1007
1008         double result = 0;
1009         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1010         char result_buf[MAX_RESULT_LENGTH] = { 0 };
1011         int str_len = 0;
1012         char error_msg[MAX_ERROR_MESSAGE_LENGTH] = { 0 };
1013         calc_expr_close_parentheses(calculator_input_str);
1014         _calc_entry_text_set(entry, calculator_input_str);
1015         snprintf(str_buf, sizeof(str_buf), "%s", calculator_input_str);
1016         str_len = strlen(str_buf);
1017         if (str_len == 0) {
1018                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1019                 return;
1020         }
1021
1022         PLOG("calculate :%s\n", str_buf);
1023         if (!calculator_calculate(str_buf, &result, error_msg)) {
1024                 PLOG("error : %s\n", error_msg);
1025                 __calculator_wrong_format_create(error_msg);
1026                 calculator_state = CALCULATOR_ERROR_OCCURED;
1027                 return;
1028         } else {
1029                 last_result = result;
1030                 memset(result_buf, 0, CALCULATOR_CONTENT_LEN + 1);
1031                 calc_expr_num_format_result(result, result_buf);
1032                 /* save result */
1033
1034                 struct history_item item;
1035                 memset(item.expression, 0, sizeof(item.expression));
1036                 memset(item.result, 0, sizeof(item.result));
1037                 calc_expr_format_expression(calculator_input_str,
1038                                             item.expression);
1039                 calc_expr_format_expression(result_buf, item.result);
1040 #ifdef SAVE_HISTORY
1041                 calc_view_save_history(item);
1042 #endif
1043
1044                 /* show result */
1045                 calculator_state = CALCULATOR_CALCULATED;
1046                 calc_view_show_result(item.result, ad);
1047
1048         }
1049         CONV_FUNC_OUT();
1050 }
1051
1052 /**
1053 * @describe
1054 *
1055 *
1056 * @param        entry
1057 * @return       void
1058 * @exception    none
1059 */
1060 static void __calculator_parenthesis_clicked(Evas_Object * entry)
1061 {
1062         CONV_FUNC_IN();
1063         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1064         snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1065         if (calculator_state == CALCULATOR_CALCULATED) {
1066                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1067
1068                 char temp[MAX_RESULT_LENGTH] = { 0 };
1069
1070                 calc_expr_num_format_result(last_result, temp);
1071                 _calc_entry_clear(entry);
1072
1073                 if (temp[0] == '-' || strchr(temp, 'E') != NULL)        //result < 0 or science number
1074                 {
1075                         _calc_entry_text_insert(entry, "((");
1076                         _calc_entry_text_insert(entry, temp);
1077                         _calc_entry_text_insert(entry, ")");
1078                 } else {
1079                         _calc_entry_text_insert(entry, "(");
1080                         _calc_entry_text_insert(entry, temp);
1081                 }
1082                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1083                 return;
1084         }
1085         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1086         int input_len = 0;
1087         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1088         input_len = strlen(before_cursor);
1089
1090         if (input_len == 0) {
1091                 _calc_entry_text_insert(entry, "(");
1092                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1093                 return;
1094         }
1095         int bracket_num = calculator_get_open_braket(all_input);
1096         if (input_len > 0) {
1097                 if (before_cursor[input_len - 1] == decimal_ch) {
1098                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1099                         return;
1100                 } else if (bracket_num > 0      //'(' is more than ')'
1101                            && before_cursor[input_len - 1] != '('
1102                            && (before_cursor[input_len - 1] == ')'
1103                                || isdigit(before_cursor[input_len - 1])
1104                                ||
1105                                (__calculator_string_get_char_type
1106                                 (before_cursor[input_len - 1]) == CHAR_IS_PI
1107                                 ||
1108                                 __calculator_string_get_char_type
1109                                 (before_cursor[input_len - 1]) == CHAR_IS_E))) {
1110                         _calc_entry_text_insert(entry, ")");
1111                         return;
1112                 } else if (bracket_num == 0) {
1113                         if (calc_expr_get_left_parentheses_num
1114                             (calculator_input_str) < MAX_PARENTHESES_NUM) {
1115                                 _calc_entry_text_insert(entry, "(");
1116                         }
1117                         return;
1118                 } else if (before_cursor[input_len - 1] != ')') //'(' is less than ')'!isdigit(before_cursor[input_len-1])&&(
1119                 {
1120                         if (calc_expr_get_left_parentheses_num
1121                             (calculator_input_str) < MAX_PARENTHESES_NUM) {
1122                                 _calc_entry_text_insert(entry, "(");
1123                         }
1124                         return;
1125                 }
1126         }
1127         CONV_FUNC_OUT();
1128         return;
1129 }
1130
1131 /**
1132 * @describe
1133 *
1134 *
1135 * @param        entry
1136 * @param        op_item
1137 * @return       void
1138 * @exception
1139 */
1140 static void
1141 __calculator_control_functions_button_clicked(Evas_Object * entry,
1142                                               op_item_t * op_item)
1143 {
1144         CONV_FUNC_IN();
1145
1146         char *str = NULL;
1147         function_t function = { 0 };
1148
1149         memset(&function, 0x0, sizeof(function_t));
1150         str = op_item->op_name;
1151
1152         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1153         int input_len = 0;
1154         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1155         int before_len = 0;
1156         last_char_t last_char_type = 0;
1157
1158         snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1159         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1160         input_len = strlen(all_input);
1161         before_len = strlen(before_cursor);
1162         if(before_len > 0){
1163                 last_char_type = __calculator_string_get_char_type(before_cursor[before_len - 1]);
1164         }
1165
1166         switch (op_item->op_id) {
1167         case OP_PERCENT:
1168                 /* if it is calculated state */
1169                 if (calculator_state == CALCULATOR_CALCULATED) {
1170                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1171                                                 "");
1172
1173                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1174                         double per_result = last_result / 100.0;
1175
1176                         calc_expr_num_format_result(per_result, temp);
1177                         _calc_entry_clear(entry);
1178
1179                         if (strcmp(temp, "0") == 0) {
1180                                 _calc_entry_text_insert(entry, "0");
1181                         } else if (temp[0] == '-')      //result < 0
1182                         {
1183                                 _calc_entry_text_insert(entry, "(");
1184                                 _calc_entry_text_insert(entry, temp);
1185                                 _calc_entry_text_insert(entry, ")");
1186                         } else {
1187                                 _calc_entry_text_insert(entry, temp);
1188                         }
1189                         calculator_state = CALCULATOR_OPERAND_INPUT;
1190                         return;
1191                 }
1192
1193                 {
1194                         int from_pos, end_pos;
1195                         char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
1196                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1197                         double per_result = 0.0;
1198
1199                         if (false ==
1200                             __calculator_get_cursor_position_float_string
1201                             (all_input, str_num, calculator_cursor_pos,
1202                              &from_pos, &end_pos)) {
1203                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1204                                 return;
1205                         }
1206
1207                         {
1208                                 if (strlen(str_num) == 0) {
1209                                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1210                                         return;
1211                                 }
1212
1213                                 if (strcmp(str_num, "0") == 0) {
1214                                         return;
1215                                 }
1216
1217                                 per_result = atof(str_num);
1218                                 per_result /= 100.0;
1219
1220                                 calc_expr_num_format_result(per_result, temp);
1221
1222                                 _calc_entry_text_remove(entry, from_pos,
1223                                                         end_pos);
1224                                 _calc_entry_text_insert(entry, temp);
1225
1226                                 calculator_state = CALCULATOR_OPERAND_INPUT;
1227                                 return;
1228                         }
1229                 }
1230                 break;
1231         case OP_PI:
1232                 if (calculator_state == CALCULATOR_CALCULATED) {
1233                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1234                                                 "");
1235                         _calc_entry_clear(entry);
1236                         _calc_entry_text_insert(entry, "p");
1237                         break;
1238                 }
1239                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1240                     && (before_cursor[before_len - 1] != '-')
1241                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1242                     && (before_cursor[before_len - 1] != '^')
1243                     && (before_cursor[before_len - 1] != '(')
1244                     && (before_cursor[before_len - 1] != 'P')
1245                     && before_cursor[before_len - 1] != 'C') {
1246                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1247                         break;
1248                 }
1249                 _calc_entry_text_insert(entry, "p");
1250                 break;
1251
1252         case OP_E:
1253                 if (calculator_state == CALCULATOR_CALCULATED) {
1254                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1255                                                 "");
1256
1257                         _calc_entry_clear(entry);
1258                         _calc_entry_text_insert(entry, op_item->op_name);
1259                         break;
1260                 }
1261                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1262                     && (before_cursor[before_len - 1] != '-')
1263                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1264                     && (before_cursor[before_len - 1] != '^')
1265                     && (before_cursor[before_len - 1] != '(')
1266                     && (before_cursor[before_len - 1] != 'P')
1267                     && before_cursor[before_len - 1] != 'C') {
1268                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1269                         break;
1270                 }
1271                 _calc_entry_text_insert(entry, op_item->op_name);
1272                 break;
1273
1274         case OP_SIN:            //sin()
1275         case OP_COS:            //cos()
1276         case OP_TAN:            //tan()
1277         case OP_LOG:            //log()
1278         case OP_ABS:            //abs()
1279                 if (calculator_state == CALCULATOR_CALCULATED) {
1280                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1281                                                 "");
1282
1283                         _calc_entry_clear(entry);
1284                         _calc_entry_text_insert(entry, op_item->op_name);
1285                         break;
1286                 }
1287                 if (last_char_type == CHAR_IS_PI || last_char_type == CHAR_IS_E) {
1288                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1289                         break;
1290                 }
1291
1292                 _calc_entry_text_insert(entry, op_item->op_name);
1293                 break;
1294
1295         case OP_LN:             //ln()
1296                 if (calculator_state == CALCULATOR_CALCULATED) {
1297                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1298                                                 "");
1299                         _calc_entry_clear(entry);
1300                         _calc_entry_text_insert(entry, op_item->op_name);
1301                         break;
1302                 }
1303                 if (last_char_type == CHAR_IS_PI) {
1304                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1305                         break;
1306                 }
1307                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1308                     && (before_cursor[before_len - 1] != '-')
1309                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1310                     && (before_cursor[before_len - 1] != '^')
1311                     && (before_cursor[before_len - 1] != '(')
1312                     && (before_cursor[before_len - 1] != 'C')
1313                     && (before_cursor[before_len - 1] != 'P')) {
1314                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1315                         break;
1316                 }
1317                 _calc_entry_text_insert(entry, op_item->op_name);
1318                 break;
1319
1320         case OP_ROOT:           //sqrt()
1321                 if (calculator_state == CALCULATOR_CALCULATED) {
1322                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1323                                                 "");
1324
1325                         _calc_entry_clear(entry);
1326                         _calc_entry_text_insert(entry, op_item->op_name);
1327                         break;
1328                 }
1329                 if (last_char_type == CHAR_IS_PI) {
1330                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1331                         break;
1332                 }
1333                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1334                     && (before_cursor[before_len - 1] != '-')
1335                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1336                     && (before_cursor[before_len - 1] != '^')
1337                     && (before_cursor[before_len - 1] != '(')
1338                     && (before_cursor[before_len - 1] != 'C')
1339                     && (before_cursor[before_len - 1] != 'P')) {
1340                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1341                         break;
1342                 }
1343                 _calc_entry_text_insert(entry, op_item->op_name);
1344                 break;
1345
1346         case OP_EX:             //e^
1347                 if (calculator_state == CALCULATOR_CALCULATED) {
1348                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1349                                                 "");
1350                         _calc_entry_clear(entry);
1351                         _calc_entry_text_insert(entry, op_item->op_name);
1352                         break;
1353                 }
1354                 if (last_char_type == CHAR_IS_PI) {
1355                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1356                         break;
1357                 }
1358                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1359                     && (before_cursor[before_len - 1] != '-')
1360                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1361                     && (before_cursor[before_len - 1] != '^')
1362                     && (before_cursor[before_len - 1] != '(')
1363                     && (before_cursor[before_len - 1] != 'C')
1364                     && (before_cursor[before_len - 1] != 'P')) {
1365                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1366                         break;
1367                 }
1368                 _calc_entry_text_insert(entry, op_item->op_name);
1369                 break;
1370
1371         case OP_X2:             //x^2
1372                 if (calculator_state == CALCULATOR_CALCULATED) {
1373                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1374                                                 "");
1375
1376                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1377                         calc_expr_num_format_result(last_result, temp);
1378                         _calc_entry_clear(entry);
1379
1380                         if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or science number
1381                         {
1382                                 _calc_entry_text_insert(entry, "(");
1383                                 _calc_entry_text_insert(entry, temp);
1384                                 _calc_entry_text_insert(entry, ")");
1385                         } else {
1386                                 _calc_entry_text_insert(entry, temp);
1387                         }
1388                         _calc_entry_text_insert(entry, op_item->op_name);
1389                         calculator_state = CALCULATOR_OPERAND_INPUT;
1390                         //use_last_result = 1;
1391                         return;
1392                 }
1393
1394                 if (input_len == 0) {
1395                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1396                         break;
1397                 }
1398                 if (last_char_type == CHAR_IS_PI) {
1399                         _calc_entry_text_insert(entry, op_item->op_name);
1400                         calculator_state = CALCULATOR_OPERAND_INPUT;
1401                         break;
1402                 } else if ((before_len > 0)
1403                            && (!isdigit(before_cursor[before_len - 1]))
1404                            && (before_cursor[before_len - 1] != ')')) {
1405                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1406                         break;
1407                 }
1408                 _calc_entry_text_insert(entry, op_item->op_name);
1409                 calculator_state = CALCULATOR_OPERAND_INPUT;
1410                 break;
1411         case OP_XY:             //x^y
1412                 if (calculator_state == CALCULATOR_CALCULATED) {
1413                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1414                                                 "");
1415
1416                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1417
1418                         calc_expr_num_format_result(last_result, temp);
1419                         _calc_entry_clear(entry);
1420
1421                         if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or science number
1422                         {
1423                                 _calc_entry_text_insert(entry, "(");
1424                                 _calc_entry_text_insert(entry, temp);
1425                                 _calc_entry_text_insert(entry, ")");
1426                         } else {
1427                                 _calc_entry_text_insert(entry, temp);
1428                         }
1429                         _calc_entry_text_insert(entry, op_item->op_name);
1430                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1431                         return;
1432                 }
1433
1434                 if (input_len == 0) {
1435                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1436                         break;
1437                 }
1438                 if ((last_char_type == CHAR_IS_PI)
1439                     || (last_char_type == CHAR_IS_E)) {
1440                         _calc_entry_text_insert(entry, op_item->op_name);
1441                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1442                         break;
1443                 } else if ((before_len > 0)
1444                            && !isdigit(before_cursor[before_len - 1])
1445                            && (before_cursor[before_len - 1] != ')')) {
1446                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1447                         break;
1448                 }
1449                 _calc_entry_text_insert(entry, op_item->op_name);
1450                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1451                 break;
1452
1453         case OP_FACT:           //x!
1454                 if (calculator_state == CALCULATOR_CALCULATED) {
1455                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1456                                                 "");
1457
1458                         char temp[MAX_RESULT_LENGTH] = { 0 };
1459
1460                         calc_expr_num_format_result(last_result, temp);
1461
1462                         if (strchr(temp, decimal_ch) != NULL || strchr(temp, '-') != NULL)      //revise by bfl
1463                         {
1464                                 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1465                                 calculator_state = CALCULATOR_WAITING_INPUT;    //revise by bfl
1466                                 return;
1467                         }
1468
1469                         _calc_entry_clear(entry);
1470                         _calc_entry_text_insert(entry, "(");
1471                         _calc_entry_text_insert(entry, temp);
1472                         _calc_entry_text_insert(entry, "!)");
1473
1474                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1475                         return;
1476                 }
1477
1478                 if (input_len == 0) {
1479                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_FAC);
1480                         break;
1481                 }
1482                 if ((last_char_type == CHAR_IS_PI)
1483                     || (last_char_type == CHAR_IS_E)) {
1484                         __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1485                         break;
1486                 }
1487
1488                 /* check if it is natural */
1489                 {
1490                         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1491                         int from_pos = 0, end_pos = 0;
1492
1493                         if (false ==
1494                             __calculator_get_cursor_position_float_string
1495                             (all_input, str_buf, calculator_cursor_pos,
1496                              &from_pos, &end_pos)) {
1497                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1498                                 break;
1499                         }
1500
1501                         if (strchr(str_buf, decimal_ch) != NULL
1502                             || str_buf[0] == '-') {
1503                                 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1504                                 break;
1505                         }
1506
1507                         _calc_entry_text_remove(entry, from_pos, end_pos);
1508                         _calc_entry_text_insert(entry, "(");
1509                         _calc_entry_text_insert(entry, str_buf);
1510                         _calc_entry_text_insert(entry, "!)");
1511                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1512                 }
1513                 break;
1514 /* @ attention
1515     This is redundant comment.
1516     Its only use is for Klocwork testing.
1517     The comment rete should passed 25%.
1518     But we have only one day to do this work.
1519     So, sorry, I will delete this comment and add useful comment later.
1520 */
1521         case OP_1X:
1522                 if (calculator_state == CALCULATOR_CALCULATED) {
1523                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1524                                                 "");
1525
1526                         char temp[MAX_RESULT_LENGTH] = { 0 };
1527                         int i = 0;
1528
1529                         calc_expr_num_format_result(last_result, temp);
1530                         if (strchr(temp, 'E') != NULL)  //science number
1531                         {
1532                                 temp[strlen(temp)] = ')';
1533                                 for (i = strlen(temp); i > 0; --i) {
1534                                         temp[i] = temp[i - 1];
1535                                 }
1536                                 temp[0] = '(';
1537                         }
1538
1539                         _calc_entry_clear(entry);
1540                         if (temp[0] == '-') {
1541                                 _calc_entry_text_insert(entry, "(-1");
1542                                 _calc_entry_text_insert(entry, "/");
1543
1544                                 _calc_entry_text_insert(entry, &temp[1]);
1545                                 _calc_entry_text_insert(entry, ")");
1546                         } else {
1547                                 _calc_entry_text_insert(entry, "(1");
1548                                 _calc_entry_text_insert(entry, "/");
1549
1550                                 _calc_entry_text_insert(entry, temp);
1551                                 _calc_entry_text_insert(entry, ")");
1552                         }
1553
1554                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1555                         //use_last_result = 1;
1556                         return;
1557                 }
1558 /* @ attention
1559     This is redundant comment.
1560     Its only use is for Klocwork testing.
1561     The comment rete should passed 25%.
1562     But we have only one day to do this work.
1563     So, sorry, I will delete this comment and add useful comment later.
1564 */
1565                 if (input_len == 0) {
1566                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1567                         break;
1568                 }
1569
1570                 /* check if it is digit */
1571                 {
1572                         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1573                         int from_pos = 0, end_pos = 0;
1574
1575                         if (false ==
1576                             __calculator_get_cursor_position_float_string
1577                             (all_input, str_buf, calculator_cursor_pos,
1578                              &from_pos, &end_pos)) {
1579                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1580                                 break;
1581                         }
1582
1583                         if (strcmp(str_buf, "p") && strcmp(str_buf, "e")
1584                             && atof(str_buf) == 0) {
1585                                 __calculator_wrong_format_create(CALC_MSG_DIVIDE_BY_ZERO);
1586                                 break;
1587                         }
1588
1589                         _calc_entry_text_remove(entry, from_pos, end_pos);
1590                         if (str_buf[0] == '-') {
1591                                 _calc_entry_text_insert(entry, "(-1");
1592                                 _calc_entry_text_insert(entry, "/");
1593
1594                                 _calc_entry_text_insert(entry, &str_buf[1]);
1595                                 _calc_entry_text_insert(entry, ")");
1596                         } else {
1597                                 _calc_entry_text_insert(entry, "(1");
1598                                 _calc_entry_text_insert(entry, "/");
1599
1600                                 _calc_entry_text_insert(entry, str_buf);
1601                                 _calc_entry_text_insert(entry, ")");
1602                         }
1603
1604                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1605                 }
1606                 break;
1607
1608         default:
1609                 break;
1610         }
1611         calculator_state = CALCULATOR_SPECIAL_FUNCTION_INPUT;
1612         CONV_FUNC_OUT();
1613         return;
1614 }
1615
1616 /////////////////////////// input text finish ////////////////////////////
1617
1618 /**
1619 * @describe
1620 *
1621 *
1622 * @param    evas_obj
1623 * @param    obj
1624 * @return    void
1625 * @exception
1626 */
1627 static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
1628 {
1629         CONV_FUNC_IN();
1630
1631         int val = 0;
1632         if (evas_obj == edje_object_part_object_get(obj, "item_brack")) {
1633                 val = OP_PARENTHESIS;
1634         } else if (evas_obj == edje_object_part_object_get(obj, "item_del")) {
1635                 val = OP_DELETE;
1636         } else if (evas_obj == edje_object_part_object_get(obj, "item_c")) {
1637                 val = OP_CLEAR;
1638         } else if (evas_obj == edje_object_part_object_get(obj, "item_div")) {
1639                 val = OP_DIVIDE;
1640         } else if (evas_obj == edje_object_part_object_get(obj, "item_num7")) {
1641                 val = OP_NUM_7;
1642         } else if (evas_obj == edje_object_part_object_get(obj, "item_num8")) {
1643                 val = OP_NUM_8;
1644         } else if (evas_obj == edje_object_part_object_get(obj, "item_num9")) {
1645                 val = OP_NUM_9;
1646         } else if (evas_obj == edje_object_part_object_get(obj, "item_mul")) {
1647                 val = OP_MULTIPLY;
1648         } else if (evas_obj == edje_object_part_object_get(obj, "item_num4")) {
1649                 val = OP_NUM_4;
1650         } else if (evas_obj == edje_object_part_object_get(obj, "item_num5")) {
1651                 val = OP_NUM_5;
1652         } else if (evas_obj == edje_object_part_object_get(obj, "item_num6")) {
1653                 val = OP_NUM_6;
1654         } else if (evas_obj == edje_object_part_object_get(obj, "item_sub")) {
1655                 val = OP_MINUS;
1656         } else if (evas_obj == edje_object_part_object_get(obj, "item_num1")) {
1657                 val = OP_NUM_1;
1658         } else if (evas_obj == edje_object_part_object_get(obj, "item_num2")) {
1659                 val = OP_NUM_2;
1660         } else if (evas_obj == edje_object_part_object_get(obj, "item_num3")) {
1661                 val = OP_NUM_3;
1662         } else if (evas_obj == edje_object_part_object_get(obj, "item_plus")) {
1663                 val = OP_PLUS;
1664         } else if (evas_obj == edje_object_part_object_get(obj, "item_dot")) {
1665                 val = OP_DOT;
1666         } else if (evas_obj == edje_object_part_object_get(obj, "item_num0")) {
1667                 val = OP_NUM_0;
1668         } else if (evas_obj == edje_object_part_object_get(obj, "item_neg")) {
1669                 val = OP_PLUS_MINUS;
1670         } else if (evas_obj == edje_object_part_object_get(obj, "item_eq")) {
1671                 val = OP_EQUAL;
1672         } else if (evas_obj == edje_object_part_object_get(obj, "item_per")) {
1673                 val = OP_PERCENT;
1674         } else if (evas_obj == edje_object_part_object_get(obj, "item_sqr")) {
1675                 val = OP_ROOT;
1676         } else if (evas_obj == edje_object_part_object_get(obj, "item_fac")) {
1677                 val = OP_FACT;
1678         } else if (evas_obj == edje_object_part_object_get(obj, "item_sin")) {
1679                 val = OP_SIN;
1680         } else if (evas_obj == edje_object_part_object_get(obj, "item_cos")) {
1681                 val = OP_COS;
1682         } else if (evas_obj == edje_object_part_object_get(obj, "item_tan")) {
1683                 val = OP_TAN;
1684         } else if (evas_obj == edje_object_part_object_get(obj, "item_ln")) {
1685                 val = OP_LN;
1686         } else if (evas_obj == edje_object_part_object_get(obj, "item_log")) {
1687                 val = OP_LOG;
1688         } else if (evas_obj == edje_object_part_object_get(obj, "item_1x")) {
1689                 val = OP_1X;
1690         } else if (evas_obj == edje_object_part_object_get(obj, "item_ex")) {
1691                 val = OP_EX;
1692         } else if (evas_obj == edje_object_part_object_get(obj, "item_x2")) {
1693                 val = OP_X2;
1694         } else if (evas_obj == edje_object_part_object_get(obj, "item_xy")) {
1695                 val = OP_XY;
1696         } else if (evas_obj == edje_object_part_object_get(obj, "item_abs")) {
1697                 val = OP_ABS;
1698         } else if (evas_obj == edje_object_part_object_get(obj, "item_pi")) {
1699                 val = OP_PI;
1700         } else if (evas_obj == edje_object_part_object_get(obj, "item_e")) {
1701                 val = OP_E;
1702         }
1703         CONV_FUNC_OUT();
1704         return val;
1705 }
1706
1707 /**
1708 * @description
1709 *   Interpret all of our different signals, and do things !
1710 *
1711 * @param        data
1712 * @param        e
1713 * @param        evas_obj
1714 * @param        event_info
1715 * @return       void
1716 * @exception    none
1717 */
1718 static void
1719 _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj,
1720                    void *event_info)
1721 {
1722         CONV_FUNC_IN();
1723
1724         int val = 0;
1725         if (data && ad->popup == NULL) {
1726                 Evas_Object *obj = (Evas_Object *) data;
1727                 val = _calculator_get_input_item(evas_obj, obj);
1728                 if (ad->wrong_timer) {
1729                         ecore_timer_del(ad->wrong_timer);
1730                         ad->wrong_timer = NULL;
1731                 }
1732                 _calc_entry_text_set(ad->input_entry, calculator_input_str);
1733                 switch (val) {
1734                 case OP_DELETE:
1735                         _calc_btn_backspace_clicked(ad->input_entry);
1736                         if (ad->calc_timer) {
1737                                 ecore_timer_del(ad->calc_timer);
1738                                 ad->calc_timer = NULL;
1739                         }
1740                         ad->calc_timer =
1741                             ecore_timer_add(0.1,
1742                                             (Ecore_Task_Cb)
1743                                             __calculator_delete_long_press,
1744                                             ad->input_entry);
1745                         break;
1746                 case OP_CLEAR:
1747                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1748                                                 "");
1749                         _calc_entry_clear(ad->input_entry);
1750                         calculator_state = CALCULATOR_WAITING_INPUT;
1751                         break;
1752                 case OP_PLUS:
1753                 case OP_MINUS:
1754                 case OP_MULTIPLY:
1755                 case OP_DIVIDE:
1756                         __calculator_control_normal_func_clicked(ad->
1757                                                                  input_entry,
1758                                                                  &calc_op_item
1759                                                                  [val]);
1760                         break;
1761                 case OP_EQUAL:
1762                         __calculator_op_equal(ad->input_entry);
1763                         break;
1764                 case OP_DOT:
1765                         _calc_btn_dot_clicked(ad->input_entry);
1766                         break;
1767                 case OP_PARENTHESIS:
1768                         __calculator_parenthesis_clicked(ad->input_entry);
1769                         break;
1770                 case OP_NUM_0:
1771                 case OP_NUM_1:
1772                 case OP_NUM_2:
1773                 case OP_NUM_3:
1774                 case OP_NUM_4:
1775                 case OP_NUM_5:
1776                 case OP_NUM_6:
1777                 case OP_NUM_7:
1778                 case OP_NUM_8:
1779                 case OP_NUM_9:
1780                         __calculator_control_panel_number_button_clicked(ad->
1781                                                                          input_entry,
1782                                                                          &calc_op_item
1783                                                                          [val]);
1784                         break;
1785                 case OP_PLUS_MINUS:
1786                         __calculator_symbol_negative_clicked(ad->input_entry);
1787                         break;
1788                 case OP_PERCENT...OP_E:
1789                         __calculator_control_functions_button_clicked(ad->
1790                                                                       input_entry,
1791                                                                       &calc_op_item
1792                                                                       [val]);
1793                         break;
1794                 default:
1795                         break;
1796                 }
1797                 if (ad->svi_handle) {
1798                         svi_play_sound(ad->svi_handle, SVI_SND_TOUCH_SIP);
1799                         svi_play_vib(ad->svi_handle, SVI_VIB_TOUCH_SIP);
1800                 }
1801         }
1802
1803         CONV_FUNC_OUT();
1804 }
1805
1806 static void __calculator_wrong_format_delete(Evas_Object *in_entry)
1807 {
1808         _calc_entry_text_set(in_entry, calculator_input_str);
1809         if (ad->wrong_timer) {
1810                 ecore_timer_del(ad->wrong_timer);
1811                 ad->wrong_timer = NULL;
1812         }
1813 }
1814
1815 static void __calculator_wrong_text_set(char * wrong_string)
1816 {
1817         char buf[MAX_EXPRESSION_LENGTH] = { 0 };
1818         memset(buf, 0, sizeof(buf));
1819         snprintf(buf, sizeof(buf),
1820                  "<align=right><+ font_size=%d><color=#855B11FF>%s",
1821                  get_max_fontsize(), wrong_string);
1822         elm_entry_entry_set(ad->input_entry, buf);
1823         elm_entry_cursor_end_set(ad->input_entry);
1824         calc_view_revise_input_scroller(ad);
1825 }
1826
1827 /**
1828 * @describe
1829 *
1830 *
1831 * @param        msg
1832 * @return       void
1833 * @exception    none
1834 */
1835 static void __calculator_wrong_format_create(char * wrong_string)
1836 {
1837         __calculator_wrong_text_set(wrong_string);
1838         if (ad->wrong_timer) {
1839                 ecore_timer_del(ad->wrong_timer);
1840                 ad->wrong_timer = NULL;
1841         }
1842         ad->wrong_timer =
1843     ecore_timer_add(2,
1844                     (Ecore_Task_Cb)
1845                     __calculator_wrong_format_delete,
1846                     ad->input_entry);
1847 }
1848
1849 /* mouse up for delete button. */
1850 static void
1851 __calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
1852                         void *event_info)
1853 {
1854         if (ad->calc_timer) {
1855                 ecore_timer_del(ad->calc_timer);
1856                 ad->calc_timer = NULL;
1857         }
1858 }
1859
1860 /**
1861 * @describe
1862 *   Register clicked callback of the keys on the keypad.
1863 *
1864 * @param    keypad      the keypad
1865 * @return   void
1866 */
1867 static void _calc_view_keypad_cb_register(Evas_Object * keypad)
1868 {
1869         char *key_name[] = {
1870                 "item_per", "item_sqr", "item_fac", "item_c", "item_div",
1871                     "item_mul", "item_del",
1872                 "item_sin", "item_cos", "item_tan", "item_num7", "item_num8",
1873                     "item_num9", "item_sub",
1874                 "item_ln", "item_log", "item_1x", "item_num4", "item_num5",
1875                     "item_num6", "item_plus",
1876                 "item_ex", "item_x2", "item_xy", "item_num1", "item_num2",
1877                     "item_num3", "item_brack",
1878                 "item_abs", "item_pi", "item_e", "item_num0", "item_dot",
1879                     "item_neg", "item_eq",
1880         };
1881
1882         Evas_Object *item = NULL;
1883         int key_num = sizeof(key_name) / sizeof(key_name[0]);
1884         int i = 0;
1885
1886         for (i = 0; i < key_num; ++i) {
1887                 item =
1888                     (Evas_Object *) edje_object_part_object_get(keypad,
1889                                                                 key_name[i]);
1890                 if (item != NULL) {
1891                         evas_object_event_callback_add(item,
1892                                                        EVAS_CALLBACK_MOUSE_DOWN,
1893                                                        _calculator_interp,
1894                                                        (void *)keypad);
1895                         if (0 == strcmp(key_name[i], "item_del")) {
1896                                 evas_object_event_callback_add(item,
1897                                                                EVAS_CALLBACK_MOUSE_UP,
1898                                                                __calculator_delelte_up,
1899                                                                (void *)keypad);
1900                         }
1901
1902                 }
1903         }
1904 }
1905
1906 /**
1907 * @description
1908 *   The callback of input entry when mouse up.
1909 *
1910 * @param    data        unused
1911 * @param    e           unused
1912 * @param    entry       the input entry
1913 * @param    event_info  unused
1914 * @return   void
1915 */
1916 static void
1917 _calc_view_input_entry_mouseup_cb(void *data, Evas * e, Evas_Object * entry,
1918                                   void *event_info)
1919 {
1920         calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for  softkey input and mouse move
1921 }
1922
1923 static void
1924 _calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
1925 {
1926         strncpy(internal_str, entry_str, buf_size - 1);
1927         /* remove result that behind '='(include '=') */
1928         char *enter = strchr(internal_str, '=');
1929         if (enter != NULL) {
1930                 enter--;
1931                 *enter = '\0';
1932         }
1933         calc_expr_replace_from_special_char(internal_str);
1934         /* remove all ','  and '\n'*/
1935         int i = 0;
1936         int j = 0;
1937         while (internal_str[j] != '\0'){
1938
1939                 if (internal_str[j] == separator_ch || internal_str[j] == '\n'){
1940                         j++;
1941                 } else {
1942                         internal_str[i++] = internal_str[j++];
1943                 }
1944         }
1945         internal_str[i] = '\0';
1946
1947 }
1948
1949 #ifdef __i386__
1950 static void
1951 _calc_view_input_entry_keyup_cb(void *data, Evas * e, Evas_Object * entry,
1952                                 void *event_info)
1953 {
1954         calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for hardkey input     
1955         if (data) {
1956                 Evas_Event_Key_Up *evt = (Evas_Event_Key_Up *) event_info;
1957                 printf("keyname: %s\n", (char *)evt->keyname);
1958                 if ((0 == strcmp(evt->keyname, "XF86Phone"))||
1959                         (0 == strcmp(evt->keyname, "XF86PowerOff"))|| 
1960                         (0 == strcmp(evt->keyname, "XF86AudioRaiseVolume"))||
1961                         (0 == strcmp(evt->keyname, "XF86AudioLowerVolume"))){
1962                         return;
1963                 }
1964                 _calc_entry_backspace(ad->input_entry);
1965         }
1966 }
1967 #endif
1968 static bool
1969 _calc_view_input_entry_error_include(char *string)
1970 {
1971     int i = 0;
1972     for(; i < ARRAY_SIZE(error_string); i++)
1973         {
1974                 if(!strcmp(string, _(error_string[i]))){
1975                         return TRUE;
1976             }
1977     }
1978     return FALSE;
1979 }
1980
1981 /**
1982 * @description
1983 *   The callback of input entry when text changed.
1984 *
1985 * @param    data        the appdata
1986 * @param    [in]obj     the input entry
1987 * @param    event_info  unused
1988 * @return   void
1989 */
1990 static void
1991 _calc_view_input_entry_changed_cb(void *data, Evas_Object * obj,
1992                                   void *event_info)
1993 {
1994         struct appdata *ad = (struct appdata *)data;
1995         PLOG("Input entry test changed\n");     /* Don't remove the log. It can guard against recursion. */
1996         const char *str = (char *)elm_entry_entry_get(obj);
1997
1998         if (paste_flag) {
1999                 char *entry_tmp = elm_entry_markup_to_utf8(str);
2000                 char *entry_expr= elm_entry_markup_to_utf8(entry_tmp);/*because the string format from clipboard is not correct*/
2001                 char internal_expr[MAX_EXPRESSION_LENGTH] = { 0 };
2002                 char f_number_buf[NUMBER_LENGTH] = { 0 };
2003                 char s_number_buf[NUMBER_LENGTH] = { 0 };
2004                 paste_flag = FALSE;
2005                 _calc_view_input_entry_to_str(entry_expr, internal_expr,
2006                                               MAX_EXPRESSION_LENGTH);
2007                 int index = 0;
2008                 bool char_in =__calculator_string_invalid_char_search(internal_expr, &index);
2009                 __calculator_get_cursor_position_float_string(internal_expr,
2010                                                               f_number_buf,
2011                                                               calculator_cursor_pos,
2012                                                               NULL, NULL);
2013                 int cur_pos = calc_view_cursor_get_position(ad->input_entry);
2014                 __calculator_get_cursor_position_float_string(internal_expr,
2015                                                               s_number_buf,
2016                                                               cur_pos, NULL,
2017                                                               NULL);
2018                 int nCntOp = calc_expr_get_operator_num(internal_expr);
2019
2020         if ((strlen(f_number_buf) > MAX_NUM_LENGTH)
2021                            || (strlen(s_number_buf) > MAX_NUM_LENGTH)) {
2022                         __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
2023                 } else if (nCntOp >= MAX_OPERATOR_NUM) {
2024                         __calculator_wrong_format_create(CALC_MSG_MAX_OP);
2025                 } else {
2026                         if(char_in){
2027                                 strncpy(calculator_input_str, internal_expr,
2028                                         index);
2029                                 calculator_cursor_pos = index;
2030                         }else{
2031                                 strncpy(calculator_input_str, internal_expr,
2032                                         sizeof(calculator_input_str) - 1);
2033                                 calculator_cursor_pos = cur_pos;
2034                         }
2035                         _calc_entry_text_set(ad->input_entry, calculator_input_str);
2036                 }
2037
2038                 if (entry_expr) {
2039                         free(entry_expr);
2040                 }
2041         }else{
2042                 char *entry_expr_s = elm_entry_markup_to_utf8(str);
2043                 char internal_expr_s[MAX_EXPRESSION_LENGTH] = { 0 };
2044                 _calc_view_input_entry_to_str(entry_expr_s, internal_expr_s,
2045                                                   MAX_EXPRESSION_LENGTH);
2046                 if(!_calc_view_input_entry_error_include(internal_expr_s)){
2047                         /*change calculator_input_str, after cut operation*/
2048                         strncpy(calculator_input_str, internal_expr_s,
2049                         MAX_EXPRESSION_LENGTH - 1);
2050                 }
2051         }
2052         /*
2053          * Prevent pasting images into entry.
2054          * If a image pasted, "<item absize=... href=...>" will be appended into entry.
2055          */
2056         if (strstr(str, "item") != NULL) {
2057                 int pos = 0;
2058                 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2059
2060                 while (elm_entry_cursor_prev(obj)) {
2061                         pos++;
2062                 }               /* save cursor position */
2063                 pos -= 1;       /* correct */
2064
2065                 strncpy(buf, str, sizeof(buf));
2066                 char *begin = strstr(buf, "<item");
2067                 char *end = strchr(begin, '>');
2068                 string_remove_at(buf, begin - buf, end - begin + 1);    /* remove "<item...>" */
2069                 elm_entry_entry_set(obj, buf);
2070
2071                 while (pos--) {
2072                         elm_entry_cursor_next(obj);
2073                 }               /* retrieve cursor position */
2074
2075                 calc_view_revise_input_scroller(ad);
2076         }
2077
2078 }
2079
2080 static void
2081 _calc_view_input_entry_paste_cb(void *data, Evas_Object * obj, void *event_info)
2082 {
2083         CONV_FUNC_IN();
2084         paste_flag = TRUE;
2085         strncpy(calculator_before_paste_str, calculator_input_str,
2086                 MAX_EXPRESSION_LENGTH - 1);
2087         printf("line = %d\n", __LINE__);
2088         CONV_FUNC_OUT();
2089 }
2090
2091 static void
2092 __conv_view_clear_clicked_cb(void *data, Evas_Object * obj, const char *emission, const char *source)
2093 {
2094
2095         CONV_FUNC_IN();
2096
2097         struct appdata *ad = (struct appdata *)data;
2098         elm_entry_entry_set(ad->hist_area, "");
2099         elm_entry_entry_set(ad->input_entry, "");
2100         _calc_view_clear_histroy(ad->hist_area);
2101
2102         CONV_FUNC_OUT();
2103 }
2104
2105 /**
2106 * @description
2107 *   Create an entry for inputing expression.
2108 *
2109 * @param    parent          the entry's parent
2110 * @param    ad              the appdata
2111 * @return   Evas_Object*    the input entry
2112 */
2113 static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
2114                                                   struct appdata *ad)
2115 {
2116         CONV_FUNC_IN();
2117         Evas_Object *entry = elm_entry_add(ad->edje);
2118         elm_entry_single_line_set(entry, EINA_FALSE);
2119         elm_entry_line_wrap_set(entry, ELM_WRAP_WORD);
2120         elm_entry_editable_set(entry, EINA_TRUE);
2121         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
2122         elm_entry_entry_set(entry, "");
2123         elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_NO_IMAGE);
2124         elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
2125         elm_entry_cursor_end_set(entry);
2126         elm_object_style_set(entry, "black");
2127         evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND,
2128                                          EVAS_HINT_EXPAND);
2129         evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
2130
2131         evas_object_event_callback_add(entry, EVAS_CALLBACK_MOUSE_UP,
2132                                        _calc_view_input_entry_mouseup_cb, ad);
2133         evas_object_smart_callback_add(entry, "changed",
2134                                        _calc_view_input_entry_changed_cb, ad);
2135         evas_object_smart_callback_add(entry, "selection,paste",
2136                                        _calc_view_input_entry_paste_cb, ad);
2137 #ifdef __i386__
2138         evas_object_event_callback_add(entry, EVAS_CALLBACK_KEY_UP,
2139                                        _calc_view_input_entry_keyup_cb, ad);
2140 #endif
2141         evas_object_show(entry);
2142         limit_filter_data.max_char_count = 0;
2143         limit_filter_data.max_byte_count = 419 + 20;    //19*21+20//result:20
2144         elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size,
2145                                      &limit_filter_data);
2146         CONV_FUNC_OUT();
2147         return entry;
2148 }
2149
2150 /**
2151 * @description
2152 *   Create a input scrooler which around the input entry.
2153 *   It can give a input entry a scroller.
2154 *
2155 * @param    parent          the parent of input scroller
2156 * @return   Evas_Object*    the input scroller
2157 * @exception
2158 */
2159 static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
2160 {
2161         CONV_FUNC_IN();
2162         Evas_Object *scroller = elm_scroller_add(parent);
2163         elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
2164         evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
2165                                          EVAS_HINT_EXPAND);
2166         evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
2167                                         EVAS_HINT_FILL);
2168
2169         evas_object_show(scroller);
2170
2171         CONV_FUNC_OUT();
2172
2173         return scroller;
2174 }
2175
2176 /**
2177 * @description
2178 *   Create the main layout.
2179 *
2180 * @param    parent          main layout's parent
2181 * @return   Evas_Object*    when success return a layout, return NULL oppositely.
2182 */
2183 static Evas_Object *_calc_view_create_layout_main(Evas_Object * parent)
2184 {
2185         CONV_FUNC_IN();
2186
2187         if (parent == NULL) {
2188                 return NULL;
2189         }
2190
2191         Evas_Object *layout = elm_layout_add(parent);
2192         if (layout == NULL) {
2193                 return NULL;
2194         }
2195
2196         elm_layout_theme_set(layout, "standard", "window", "integration");
2197         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
2198                                          EVAS_HINT_EXPAND);
2199         elm_win_resize_object_add(parent, layout);
2200
2201         edje_object_signal_emit(_EDJ(layout), "elm,state,show,content", "elm");
2202         edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator",
2203                                 "elm");
2204         evas_object_show(layout);
2205
2206         CONV_FUNC_OUT();
2207
2208         return layout;
2209 }
2210
2211 /**
2212 * @description
2213 *   Load the main view of calculator.
2214 *   Create the input entry and keypad.
2215 *
2216 * @param    ad      the appdata
2217 * @return   void
2218 */
2219 void calc_view_load(struct appdata *ad)
2220 {
2221         CONV_FUNC_IN();
2222
2223         ad->layout = _calc_view_create_layout_main(ad->win);
2224         ad->edje = load_edj(ad->win, LAYOUT_EDJ_NAME, GRP_MAIN);
2225         evas_object_show(ad->edje);
2226         evas_object_name_set(ad->edje, "edje");
2227         elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->edje);
2228
2229         /* inititialize environment variable */
2230         locale = localeconv();
2231         decimal = locale->decimal_point;
2232         separator = locale->thousands_sep;
2233         int len_seq = strlen(separator);
2234         decimal_ch = decimal[0];
2235         separator_ch = separator[0];
2236         if (len_seq == 2 || len_seq == 0) {
2237                 separator_ch = 32;
2238         }
2239         /*init svi */
2240         svi_init(&ad->svi_handle);
2241
2242         /* input area */
2243         ad->input_entry = _calc_view_create_input_entry(ad->edje, ad);
2244         ad->input_scroller = _calc_view_create_input_scroller(ad->edje);
2245         elm_object_content_set(ad->input_scroller, ad->input_entry);
2246         edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
2247                                  ad->input_scroller);
2248         edje_object_signal_callback_add(_EDJ(ad->edje), "clicked", "",
2249                                         __conv_view_clear_clicked_cb, ad);
2250
2251         /* pannels */
2252         ad->por_pannel = load_edj(ad->edje, LAYOUT_EDJ_NAME, GRP_POR_PANNEL);
2253         edje_object_part_swallow(_EDJ(ad->edje), "por_pannel/rect",
2254                                  ad->por_pannel);
2255         edje_object_signal_emit(_EDJ(ad->edje), "portrait", "");
2256         _calc_view_keypad_cb_register(_EDJ(ad->por_pannel));
2257
2258         CONV_FUNC_OUT();
2259
2260 }
2261
2262 /**
2263 * @description
2264 *   assign global variable  , this will be removed
2265 *
2266 * @param        ad
2267 * @return       void
2268 * @exception
2269 */
2270 void calc_xxx(struct appdata *ap)
2271 {
2272         ad = ap;
2273 }