Change app icon
[apps/home/calculator.git] / src / calculator_edje.c
1 /*
2 *
3 * Copyright 2012  Samsung Electronics Co., Ltd
4 *
5 * Licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *    http://floralicense.org/license
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
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 <feedback.h>
29 #include <Ecore_X.h>
30 #include <vconf.h>
31
32 #define CALCULATOR_CHAR_IS_OPERATOR(C) ((C == '+')||(C == '-')||(C == 'x')||(C == '/')) /**<judge if a char is a basic operator*/
33 #define CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(C) ((C == 'x')||(C == '/'))                    /**<judge if an operator is "*" or "/"*/
34 #define CALCULATOR_CHAR_IS_PLUS_DEDUCT(C) ((C == '+')||(C == '-'))
35 #define CALCULATOR_CHAR_IS_DIGITAL(C)(C >= '0' && C <= '9')
36 #define CALCULATOR_IS_DIGIT_DOT(ch, decimal) (isdigit(ch) || decimal == (ch))
37
38 static Elm_Entry_Filter_Limit_Size limit_filter_data;
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 void calc_view_load(struct appdata *ad);
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 int calculator_cursor_pos = 0;
49 char calculator_input_str[MAX_EXPRESSION_LENGTH] = { 0 };
50 char calculator_before_paste_str[MAX_EXPRESSION_LENGTH] = { 0 };
51 bool paste_flag = FALSE;
52
53 struct lconv *locale = NULL;
54 char *decimal = NULL;
55 char *separator = NULL;
56 char decimal_ch = 0;
57 char separator_ch = 0;
58
59 int cur_fontsize = 70;
60 int small_fontsize = 58;
61 int default_fontsize = 0;
62 int min_len = 13;
63 int max_len = 0;
64 int scientific_result_len = 8;
65
66 bool select_mode = FALSE;
67
68 static op_item_t calc_op_item[] = {
69         {OP_INVALID, "", NULL},
70
71         /* basic */
72         {OP_PARENTHESIS, "()", NULL},
73         {OP_DELETE, "<-", NULL},
74         {OP_CLEAR, "C", NULL},
75         {OP_DIVIDE, "/", NULL},
76
77         {OP_NUM_7, "7", NULL},
78         {OP_NUM_8, "8", NULL},
79         {OP_NUM_9, "9", NULL},
80         {OP_MULTIPLY, "x", NULL},
81
82         {OP_NUM_4, "4", NULL},
83         {OP_NUM_5, "5", NULL},
84         {OP_NUM_6, "6", NULL},
85         {OP_MINUS, "-", NULL},
86
87         {OP_NUM_1, "1", NULL},
88         {OP_NUM_2, "2", NULL},
89         {OP_NUM_3, "3", NULL},
90         {OP_PLUS, "+", NULL},
91
92         {OP_DOT, ".", NULL},
93         {OP_NUM_0, "0", NULL},
94         {OP_PLUS_MINUS, "+/-", NULL},
95         {OP_EQUAL, "=", NULL},
96
97         /* functional */
98         {OP_PERCENT, "%", NULL},
99         {OP_ROOT, "sqrt", "sqrt("},
100         {OP_FACT, "x!", "!"},
101
102         {OP_SIN, "sin", "sin("},
103         {OP_COS, "cos", "cos("},
104         {OP_TAN, "tan", "tan("},
105
106         {OP_LN, "ln", "ln("},
107         {OP_LOG, "log", "log("},
108         {OP_1X, "1/x", "1/x"},
109
110         {OP_10X, "10^x", "10^("},
111         {OP_X2, "x^2", "^2"},
112         {OP_XY, "x^y", "^("},
113
114         {OP_ABS, "abs", "abs("},
115         {OP_PI, "Pi", "p"},
116         {OP_E, "e", "e"},
117 };
118 char *error_string[] = {
119     "IDS_CCL_POP_UP_TO_15_DIGITS_AVAILABLE",
120     "IDS_CCL_POP_UP_TO_5_DECIMALS_AVAILABLE",
121     "IDS_CCL_POP_UP_TO_20_OPERATORS_AVAILABLE",
122     "IDS_CCL_POP_UNABLE_TO_DIVIDE_BY_ZERO",
123     "IDS_CCL_POP_NO_NUMBER_ERROR",
124     "IDS_CCL_POP_ERROR",
125     "IDS_CCL_POP_ENTER_NUMBER_AFTER_OPERATOR",
126     "IDS_CCL_BODY_INVALID_INPUT_FOR_SQUARE_ROOT_FUNCTION",
127     "IDS_CCL_BODY_INVALID_INPUT_FOR_LOG_FUNCTION",
128     "IDS_CCL_BODY_NATURAL_NUMBER_ONLY_FOR_X_E_FUNCTION",
129     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X_E_FUNCTION",
130     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_1_X_FUNCTION",
131     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_X2_FUNCTION",
132     "IDS_CCL_BODY_ENTER_NUMBER_BEFORE_INPUTTING_XY_FUNCTION",
133     "IDS_CCL_POP_NO_OPERATOR_ERROR",
134     "IDS_CCL_POP_SYNTAX_ERROR",
135     "IDS_CCL_POP_INPUT_ERROR",
136 };
137
138 calculator_state_t calculator_get_state()
139 {
140         return calculator_state;
141 }
142
143 void _calc_add_tag(char *string, char *format_string)
144 {
145         CALC_FUN_BEG();
146         int i = 0;
147         int begin = 0;
148         int end = 0;
149         char buf[MAX_EXPRESSION_LENGTH] = { 0 };
150         char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
151         char *p = NULL;
152         while (string[i] != '\0') {
153                 if (CALCULATOR_CHAR_IS_DIGITAL(string[i])
154                     || string[i] == separator_ch || string[i] == decimal_ch
155                     ||( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92')) {
156                         if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
157                                 memset(buf, 0, sizeof(buf));
158                                 snprintf(buf, sizeof(buf),
159                                  "<align=right><font_size=%d><color=#505050FF>(<align=right><font_size=%d><color=#505050FF>-",
160                                  cur_fontsize, cur_fontsize);
161                                 strcat(format_string, buf);
162                                 i=i+4;
163                         }
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                                 i++;
170                         }
171                         end = i - 1;
172                         strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
173                         tmp[end - begin + 1] = '\0';
174                         memset(buf, 0, sizeof(buf));
175                         snprintf(buf, sizeof(buf),
176                                  "<align=right><font_size=%d><color=#505050FF>%s",
177                                  cur_fontsize, tmp);
178                         strcat(format_string, buf);
179                 } else {
180                         begin = i;
181                         p = &string[begin];
182                         while (!CALCULATOR_CHAR_IS_DIGITAL(string[i])
183                                && string[i] != separator_ch
184                                && string[i] != decimal_ch
185                                && string[i] != '\0') {
186                                if ( string[i]=='(' && string[i+1]=='\xe2' &&string[i+2]=='\x88' && string[i+3]=='\x92') {
187                                         break;
188                                } else {
189                                         i++;
190                                }
191                         }
192                         end = i - 1;
193                         strncpy(tmp, p, MAX_EXPRESSION_LENGTH - 1);
194                         tmp[end - begin + 1] = '\0';
195                         memset(buf, 0, sizeof(buf));
196                         snprintf(buf, sizeof(buf),
197                                  "<align=right><font_size=%d><color=#505050FF>%s",
198                                  cur_fontsize, tmp);
199                         strcat(format_string, buf);
200                 }
201
202         }
203         CALC_FUN_END();
204 }
205
206 /**
207 * @describe
208 * Change line and font size when it is needed.
209 * Refer to the auto font resizing rules.
210 * @param        tag_text                The text with tags.
211 * @return       void
212 * @exception
213 */
214 void _calc_add_br(char *tag_text)
215 {
216         CALC_FUN_BEG();
217         if (tag_text  == NULL) {
218                 return;
219         }
220         app_device_orientation_e curr = app_get_device_orientation();
221         if (curr  == APP_DEVICE_ORIENTATION_270 || curr == APP_DEVICE_ORIENTATION_90) {
222                 return;
223         }
224         int line_valid_num = 0;
225         int whole_valid_num = 0;
226         int operator_tag = -1;
227         int operator_location = -1;
228         /* record is there an operator in one line? */
229         bool operator_flag = FALSE;
230         /* when change to small font, we should rescan the tag_text */
231         bool rescan_flag = FALSE;
232         int cur_len = 0;
233         char buf[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
234         strcpy(buf, tag_text);
235         int br_number = 0;
236         int i = 0;
237         int j = 0;
238         for ( ; tag_text[i] != '\0' && calculator_input_str[j] != '\0'; ) {
239                 while (tag_text[i] == '<') {
240                         while (tag_text[i++] != '>') {
241                                 /* NULL */
242                                 ;
243                         }
244                 }
245                 /* if calculator_input_str[j] is "*" or "/", tag_text[i] would be
246                         "\xc3\x97" or "\xc3\xb7" */
247                 if (tag_text[i] == calculator_input_str[j] || (tag_text[i] == '\xc3') ||
248                         ((tag_text[i] == '\xe2') && (tag_text[i+1] == '\x88') && (tag_text[i+2] == '\x92'))) {
249
250                         if ((CALCULATOR_CHAR_IS_OPERATOR(calculator_input_str[j])) &&
251                                 (!(calculator_input_str[j] == '-' && calculator_input_str[j-1] == '('))) {
252                                 if (!operator_flag || rescan_flag) {
253                                         operator_location = j;
254                                         operator_tag = i;
255                                         operator_flag = TRUE;
256                                 }
257                         }
258
259                         whole_valid_num++;
260                         line_valid_num++;
261                         if (br_number < 2) {
262                                 cur_fontsize = default_fontsize;
263                                 cur_len = min_len;
264                         } else {
265                                 if ((line_valid_num >= min_len) && (!rescan_flag)) {
266                                         rescan_flag = TRUE;
267                                         cur_fontsize = small_fontsize;
268                                         strcpy(tag_text, buf);
269                                         /* restore to the original state, then scan from the begin */
270                                         i = 0;
271                                         j = 0;
272                                         whole_valid_num = 1;
273                                         line_valid_num = 1;
274                                         operator_flag = FALSE;
275                                         operator_tag = -1;
276                                         operator_location = -1;
277                                         cur_len = max_len + 1;
278                                 }
279                         }
280
281                         if (line_valid_num >= cur_len) {
282                                 if (operator_flag && operator_tag > 0) {
283                                         string_insert(tag_text, operator_tag, "<br>");
284                                         line_valid_num = whole_valid_num-operator_location;
285                                         operator_flag = FALSE;
286                                         operator_tag = -1;
287                                         operator_location = -1;
288                                 } else {
289                                         string_insert(tag_text, i, "<br>");
290                                         line_valid_num = 0;
291
292                                 }
293                                 i = i + 4;
294                                 if (br_number < 2) {
295                                         br_number++;
296                                 }
297                         }
298                         i++;
299                         j++;
300                 }else {
301                         i++;
302                 }
303     }
304     CALC_FUN_END();
305 }
306
307
308 /**
309 * @describe
310 *
311 *
312 * @param    entry
313 * @param    str
314 * @return    void
315 * @exception
316 */
317 static void _calc_entry_text_set(Evas_Object * entry, const char *str)
318 {
319         CALC_FUN_BEG();
320         if (select_mode) {
321                 select_mode = FALSE;
322         }
323         char tmp[MAX_EXPRESSION_LENGTH] = { 0 };
324         char tag_text[MAX_TAG_EXPRESSION_LENGTH] = { 0 };
325         char new_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
326         char old_font_str[MAX_EXPRESSION_LENGTH] = { 0 };
327
328         Eina_Bool status = elm_entry_editable_get(entry);
329         if (EINA_FALSE == status) {
330                 elm_entry_editable_set(entry, EINA_TRUE);//chx add recover the old style
331                 elm_entry_line_wrap_set(entry,ELM_WRAP_WORD);
332                 elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
333                 elm_object_style_set(entry, "black");
334                 elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data);
335                 elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
336         }
337
338         if (str == NULL) {
339                 return;
340         }
341
342         if (strlen(str) == 0) {
343                 elm_entry_entry_set(entry, "");
344                 elm_entry_cursor_end_set(entry);
345                 elm_object_focus_set(entry, EINA_TRUE);
346                 CALC_FUN_END();
347                 return;
348         }
349         calc_expr_format_expression(str, tmp);
350         CALC_INFO("ASCII :: expr_out = %s", tmp);
351         CALC_INFO("ASCII :: expr_out = %d", tmp);
352         _calc_add_tag(tmp, tag_text);
353         int pre_fontsize = cur_fontsize;
354         _calc_add_br(tag_text);
355         snprintf(old_font_str, sizeof(old_font_str), "=%d", pre_fontsize);
356         snprintf(new_font_str, sizeof(new_font_str), "=%d", cur_fontsize);
357         string_replace(tag_text, old_font_str, new_font_str);
358         CALC_INFO("ASCII :: tag_text = %s", tag_text);
359         CALC_INFO("ASCII :: tag_text = %d", tag_text);
360         elm_entry_entry_set(entry, tag_text);
361         if(calculator_cursor_pos == strlen(calculator_input_str)){
362                 elm_entry_cursor_end_set(entry);
363                 elm_object_focus_set(entry, EINA_TRUE);
364         }else {
365                 calc_view_cursor_set_position(entry, calculator_cursor_pos);
366         }
367         CALC_FUN_END();
368 }
369
370 void _calc_entry_text_set_rotate(struct appdata *ad)
371 {
372     CALC_FUN_BEG();
373         if (calculator_state == CALCULATOR_CALCULATED) {
374                 _calc_view_show_newest_histroy(ad->input_entry);
375                 elm_entry_cursor_end_set(ad->input_entry);
376                 elm_object_focus_set(ad->input_entry, EINA_TRUE);
377         } else {
378                 _calc_entry_text_set(ad->input_entry, calculator_input_str);
379         }
380         CALC_FUN_END();
381 }
382
383 /**
384 * @describe
385 *
386 *
387 * @param    entry
388 * @param    str
389 * @return    void
390 * @exception
391 */
392 static void _calc_entry_text_insert(Evas_Object * entry, char *str)
393 {
394         CALC_FUN_BEG();
395         CALC_INFO("ASCII :: str = %s", str);
396         CALC_INFO("ASCII :: str = %d", str);
397         calc_expr_input_insert(calculator_input_str, &calculator_cursor_pos, str);
398         _calc_entry_text_set(entry, calculator_input_str);
399         CALC_FUN_END();
400 }
401
402 /**
403 * @describe
404 *
405 *
406 * @param    entry
407 * @param    from_pos
408 * @param    end_pos
409 * @return    void
410 * @exception
411 */
412 static void _calc_entry_text_remove(Evas_Object * entry, const int from_pos,
413                                     const int end_pos)
414 {
415         CALC_FUN_BEG();
416         string_remove_at(calculator_input_str, from_pos,
417                          end_pos - from_pos + 1);
418         calculator_cursor_pos = from_pos;
419         _calc_entry_text_set(entry, calculator_input_str);
420         CALC_FUN_END();
421 }
422
423 /**
424 * @describe
425 *       Set correct cursor position in entry.
426 *
427 * @param    entry
428 * @return    void
429 * @exception
430 */
431 static void _calc_entry_cursor_set(Evas_Object * entry)
432 {
433         CALC_FUN_BEG();
434         calc_view_cursor_set_position(entry, calculator_cursor_pos);
435         CALC_FUN_END();
436 }
437
438 /**
439 * @describe
440 *
441 *
442 * @param    entry
443 * @return    void
444 * @exception
445 */
446 static void _calc_entry_backspace(Evas_Object * entry)
447 {
448         CALC_FUN_BEG();
449         calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
450         _calc_entry_text_set(entry, calculator_input_str);
451         CALC_FUN_END();
452 }
453
454 /**
455 * @describe
456 *
457 *
458 * @param    entry
459 * @return    void
460 * @exception
461 */
462 void _calc_entry_clear(Evas_Object * entry)
463 {
464         CALC_FUN_BEG();
465         memset(calculator_input_str, 0, sizeof(calculator_input_str));
466         calculator_cursor_pos = 0;
467         _calc_entry_text_set(entry, "");
468         calc_view_cursor_set_position(entry, calculator_cursor_pos);
469         CALC_FUN_END();
470 }
471
472 /* END INPUT ENTRY RELATED */
473
474 /**
475 * @describe
476 * Get the operand start and end location where the cursor in.
477 * 1.2+6.|43 (cursor is before 4), then return begin=4 end=7
478 * Espcially, cursor is after +, it means the operand which follows
479 * the operator, so it return the same result as before.
480 * This is add by on 2012/5/29
481 *
482 * @param[in]    text    The current calculator input string
483 * @param[out]   begin   The start location of an operand
484 * @param[out]   end     The end location of an operand
485 * @return               Is cursor in an operand
486 * @retval       true    The cursor is in the operand
487 * @retval       false   The cursor is not in the operand
488 * @exception
489 */
490 static bool
491 __calculator_get_float_num_in_cursor_position(char *text, int cur_pos,
492                                               int *begin, int *end)
493 {
494         CALC_FUN_BEG();
495         if (text == NULL) {
496                 return false;
497         }
498         int pos = cur_pos - 1;
499         if (pos < 0) {
500                 pos = 0;
501         }
502         int _begin = 0;
503         int _end = 0;
504
505         if ('p' == text[pos] || 'e' == text[pos]) {
506                 *begin = pos;
507                 *end = pos;
508                 return true;
509         } else if (CALCULATOR_IS_DIGIT_DOT(text[pos], decimal_ch)) {
510                 for (_begin = pos - 1;
511                      CALCULATOR_IS_DIGIT_DOT(text[_begin], decimal_ch)
512                      && _begin >= 0; --_begin) {
513                         ;       /* NULL */
514                 }
515                 _begin++;
516                 if (_begin > 1 && '-' == text[_begin - 1]
517                     && '(' == text[_begin - 2]) {
518                         _begin--;
519                 }
520                 for (_end = pos + 1;
521                      CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
522                      && _end < strlen(text); ++_end) {
523                         ;       /* NULL */
524                 }
525                 _end--;
526
527                 *begin = _begin;
528                 *end = _end;
529                 return true;
530         } else if (CALCULATOR_CHAR_IS_OPERATOR(text[pos]) || text[pos] == '(') {
531                 for (_end = pos + 1;
532                      CALCULATOR_IS_DIGIT_DOT(text[_end], decimal_ch)
533                      && _end < strlen(text); ++_end) {
534                         ;       /* NULL */
535                 }
536                 _end--;
537                 *begin = pos+1;
538                 *end = _end;
539                 return true;
540         } else {
541                 return false;
542         }
543         CALC_FUN_END();
544 }
545
546 /**
547 * @describe
548 * Get the operand start and end location where the cursor in the operand
549 * Actually, it would call "__calculator_get_float_num_in_cursor_position"
550 * function to recognize whether the cursor is in the operand.
551 *
552 * @param[in]    entry_text      The current calcualtor input string
553 * @param[out]   str     The operand which the cursor in
554 * @param[out]   from    The operand start location which contain the cursor
555 * @param[out]   end     The operand end location which contain the cursor
556 * @return               Is cursor in an operand
557 * @retval       true    The cursor is in the operand
558 * @retval       false   The cursor is not in the operand
559 * @exception
560 */
561 static bool
562 __calculator_get_cursor_position_float_string(char *entry_text, char *str,
563                                               int cur_pos, int *from, int *end)
564 {
565         CALC_FUN_BEG();
566         if (entry_text == NULL) {
567                 return false;
568         }
569         int from_pos = cur_pos;
570         int end_pos = cur_pos;
571
572         if (false ==
573             __calculator_get_float_num_in_cursor_position(entry_text, cur_pos, &from_pos, &end_pos)) {
574                 return false;
575         }
576
577         /* set from&end position */
578         if (from != NULL) {
579                 *from = from_pos;
580         }
581         if (end != NULL) {
582                 *end = end_pos;
583         }
584
585         strncpy(str, entry_text + from_pos, end_pos - from_pos + 1);
586         str[end_pos - from_pos + 1] = '\0';
587         CALC_FUN_END();
588         return true;
589 }
590
591 /**
592 * @describe
593 *   Get the float number in current cursor
594 *
595 * @param    entry_text
596 * @param    str
597 * @return    void
598 * @exception
599 */
600 static bool
601 __calculator_get_before_cursor_float_string(char *entry_text, char *str)
602 {
603         CALC_FUN_BEG();
604
605         int from_pos = calculator_cursor_pos;
606         int end_pos = calculator_cursor_pos;
607
608         if (false ==  __calculator_get_float_num_in_cursor_position(entry_text, calculator_cursor_pos, &from_pos, &end_pos)) {
609                 return false;
610         }
611         snprintf(str, calculator_cursor_pos - from_pos + 1, "%s", entry_text + from_pos);
612         CALC_FUN_END();
613         return true;
614 }
615
616 /**
617 * @describe
618 *   Get string before cursor in the Entry.
619 *
620 * @param    entry_text
621 * @param    str
622 * @return    void
623 * @exception
624 */
625 static void
626 __calculator_get_input_from_begin_to_cursor(char *entry_text, char *str)
627 {
628         CALC_FUN_BEG();
629
630         if (calculator_cursor_pos > 0) {
631                 strncpy(str, entry_text, calculator_cursor_pos);
632                 str[calculator_cursor_pos] = '\0';
633         } else {
634                 strcpy(str, "");
635         }
636         CALC_FUN_END();
637 }
638
639 /**
640 * @describe
641 *
642 * judge the type of current input
643 *
644 * @param    input
645 * @return    void
646 * @exception
647 */
648 static last_char_t __calculator_string_get_char_type( char ch_in)
649 {
650         CALC_FUN_BEG();
651         if (ch_in == '\0') {
652                 return CHAR_IS_NULL;
653         }
654         if (ch_in == 'p') {
655                 return CHAR_IS_PI;
656         }
657         if (ch_in == 'e') {
658                 return CHAR_IS_E;
659         }
660         if (CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(ch_in)) {
661                 return CHAR_IS_MULTIPLY_DIVIDE;
662         }
663         if (ch_in == '(') {
664                 return CHAR_IS_LEFT_PARENTHESE;
665         }
666         if (ch_in == ')') {
667                 return CHAR_IS_RIGHT_PARENTHESE;
668         }
669         if (CALCULATOR_CHAR_IS_DIGITAL(ch_in)) {
670                 return CHAR_IS_DIGIT;
671         }
672         if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(ch_in) ){
673                 return CHAR_IS_PLUS_MINUS;
674         }
675         if (ch_in == decimal_ch) {
676                 return CHAR_IS_POINT;
677         }
678         return CHAR_IS_CHARACTER;
679         CALC_FUN_END();
680 }
681
682 static bool  __calculator_string_digit_in(const char *input)
683 {
684         int i =0;
685         while(input[i]!='\0'){
686                 if(IS_DIGITAL(input[i])){/*here ,digit include "p" and "e"*/
687                         return TRUE;
688                 }else{
689                         i++;
690                 }
691         }
692          return FALSE;
693 }
694
695 /*
696 * search charactor in input string, if have charactor, return True and index of first charactor;
697 * else return False;
698 */
699 static bool __calculator_string_char_search(const char *input, int *index)
700 {
701         CALC_FUN_BEG();
702         if (input == NULL) {
703                 return FALSE;
704         }
705         int len_cp = strlen(input);
706         if(len_cp <= 0){
707                 return FALSE;
708         }
709         int i = 0;
710         for(; i < len_cp ; i++){
711                 last_char_t cur_char_type = __calculator_string_get_char_type(input[i]);
712                 if (CHAR_IS_CHARACTER == cur_char_type) {
713                         *index  = i;
714                         return TRUE;
715                 }
716         }
717         return FALSE;
718         CALC_FUN_END();
719 }
720
721 /*
722 * search invalid charactor in input string, if have invalid charactor, return True and index of first invalid charactor;
723 * else return False;
724 */
725 static bool __calculator_string_invalid_char_search(char *input, int *index)
726 {
727         int sub_index = 0;
728         char *p = input;
729         bool char_in = FALSE;
730         int len = 0;
731         char_in = __calculator_string_char_search(p, &sub_index);
732         if (!char_in) {/*no charactor*/
733                 return FALSE;
734         }
735                 *index += sub_index;
736                 p += sub_index;
737         while (p) {
738                 if (!__calculator_search_function(p, &len)) {/*charactor not a function*/
739                         return TRUE;
740                 } else {/*the first sevaral charactors are function, continue search*/
741                         *index += len;
742                         p += len;
743                 }
744                 /*Fix bug that paste did not filter invaild word, beacuse here it jump to
745                 *  the sub_index directly, but the sub_index would change with the string
746                 *  So, it should recalculate every time*/
747                 char_in = __calculator_string_char_search(p, &sub_index);
748                 if (char_in) {
749                         *index += sub_index;
750                         p += sub_index;
751                 } else {
752                         return FALSE;
753                 }
754         }
755         return FALSE;
756 }
757 /**
758 * @describe
759 *
760 *
761 * @param    entry
762 * @param    op_item
763 * @return    void
764 * @exception
765 */
766 static void
767 __calculator_control_panel_number_button_clicked(Evas *e, Evas_Object *entry, op_item_t *op_item)
768 {
769         CALC_FUN_BEG();
770         if (select_mode) {
771                 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
772                 if (selected_str) {
773                         if (calc_select_string_search(selected_str)) {
774                                 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym,
775                                         op_item->op_sym, op_item->op_sym, 0, NULL);
776                         } else {
777                                 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
778                                 calculator_cursor_pos = strlen(calculator_input_str);
779                         }
780                         SFREE(selected_str);
781                 }
782                 return;
783         }
784         /* replace special characters */
785         char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
786         snprintf(entry_text, sizeof(entry_text), "%s", calculator_input_str);
787         //Current state is calculated, clear all
788         if (calculator_state == CALCULATOR_CALCULATED) {
789                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
790                 _calc_entry_clear(entry);
791                 _calc_entry_text_insert(entry, op_item->op_sym);
792                 calculator_state = CALCULATOR_OPERAND_INPUT;
793                 return;
794         }
795
796         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
797         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
798         int before_len = 0;
799         int nDigitCnt = 0;
800         int nPointCnt = 0;
801         __calculator_get_cursor_position_float_string(entry_text, str_buf, calculator_cursor_pos, NULL, NULL);
802         __calculator_get_input_from_begin_to_cursor(entry_text, before_cursor);
803         before_len = strlen(before_cursor);
804         calculator_get_digits_number(str_buf, &nDigitCnt, &nPointCnt);
805         char str_bufa[MAX_EXPRESSION_LENGTH] = { 0 };
806         __calculator_get_before_cursor_float_string(entry_text, str_bufa);
807         if (strcmp(str_bufa, "0") == 0) {
808                 _calc_entry_backspace(entry);
809         }
810
811         if (strlen(str_buf) >= MAX_NUM_LENGTH) {
812                 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
813                 return;
814         } else if (nPointCnt >= MAX_DECIMAL_NUM && calculator_cursor_pos > nDigitCnt) {
815                 __calculator_wrong_format_create(CALC_MSG_MAX_DEC_DIGIT);
816                 return;
817         } else if (before_len > 0
818                    && (__calculator_string_get_char_type(before_cursor[before_len - 1]) ==
819                    CHAR_IS_PI
820                    || __calculator_string_get_char_type(before_cursor[before_len - 1]) ==
821                    CHAR_IS_E)) {
822                 /* input digital after "e" or "p", the "x" opeartor will be added automatically */
823                 _calc_entry_text_insert(entry, "x");
824                 _calc_entry_text_insert(entry, op_item->op_sym);
825                 calculator_state = CALCULATOR_OPERAND_INPUT;
826                 return;
827         } else if (before_len > 0 && ((before_cursor[before_len - 1] == '(') ||CALCULATOR_CHAR_IS_DIGITAL(before_cursor[before_len - 1])
828                        || CALCULATOR_CHAR_IS_OPERATOR(before_cursor[before_len - 1]) || (int)before_cursor[before_len - 1] > 120))      //* or/
829         {
830                 _calc_entry_text_insert(entry, op_item->op_sym);
831                 calculator_state = CALCULATOR_OPERAND_INPUT;
832                 return;
833         } else if (before_len > 0 && (before_cursor[before_len - 1] == ')')) {
834                 __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
835                 return;
836         } else {
837                 _calc_entry_text_insert(entry, op_item->op_sym);
838                 calculator_state = CALCULATOR_OPERAND_INPUT;
839                 return;
840         }
841         CALC_FUN_END();
842 }
843
844 /**
845 * @describe
846 * Deal the event when dot clicked on the keyboard
847 *
848 * @param[in]    entry   The input entry
849 * @return               void
850 * @exception
851 */
852 static void _calc_btn_dot_clicked(Evas_Object *entry)
853 {
854         CALC_FUN_BEG();
855         if (entry == NULL) {
856                 return;
857         }
858         char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
859         int str_num_len = 0;
860
861         char decimal_str[32] = { 0 };
862
863         /* replace special characters */
864         char entry_text[MAX_EXPRESSION_LENGTH] = { 0 };
865         strncpy(entry_text, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
866
867         if (calculator_state == CALCULATOR_CALCULATED) {
868                 _calc_entry_clear(entry);
869                 memset(entry_text,0x00,sizeof(entry_text));
870         }
871
872         int from_pos = 0;
873         int end_pos = 0;
874         if (!__calculator_get_cursor_position_float_string
875             (entry_text, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
876                 if (calculator_cursor_pos == 0
877                     || IS_OPERATOER(calculator_input_str[from_pos - 1])
878                         || calculator_input_str[from_pos - 1] == '(') {
879                         snprintf(decimal_str, sizeof(decimal_str), "0%c",
880                                  decimal_ch);
881                         _calc_entry_text_insert(entry, decimal_str);
882                         calculator_state = CALCULATOR_OPERAND_INPUT;
883                         return;
884                 }
885                 return;
886         } else {
887                 if (strcmp(str_num, "p") == 0 || strcmp(str_num, "e") == 0) {
888                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
889                         return;
890                 }
891         }
892
893         str_num_len = strlen(str_num);
894         if (str_num_len > 0 && str_num[str_num_len - 1] == decimal_ch) {
895                 return;
896         }
897
898         int nDigitCnt = 0;
899         int nPointCnt = 0;
900         calculator_get_digits_number(str_num, &nDigitCnt, &nPointCnt);
901
902         if (nDigitCnt >= 15) {
903                 __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
904                 return;
905         }
906
907         if (nPointCnt > 0) {
908                 return;
909         }
910         if (IS_OPERATOER(calculator_input_str[calculator_cursor_pos-1])
911                 || calculator_input_str[calculator_cursor_pos-1] == '(') {
912                 snprintf(decimal_str, sizeof(decimal_str), "0%c", decimal_ch);
913         } else {
914                 snprintf(decimal_str, sizeof(decimal_str), "%c", decimal_ch);
915         }
916         _calc_entry_text_insert(entry, decimal_str);
917         calculator_state = CALCULATOR_OPERAND_INPUT;
918         CALC_FUN_END();
919         return;
920 }
921
922 /**
923 * @describe
924 *
925 *
926 * @param        entry
927 * @return       void
928 * @exception
929 */
930 static void _calc_btn_backspace_clicked(Evas *e, Evas_Object *entry)
931 {
932         CALC_FUN_BEG();
933         if (select_mode) {
934                 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
935                 if (selected_str) {
936                         if (calc_select_string_search(selected_str)) {
937                                 evas_event_feed_key_down(e, "KP_BACKSPACE", "", "", "", 0, NULL);
938                         } else {
939                                 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
940                                 calculator_cursor_pos = strlen(calculator_input_str);
941                         }
942                         SFREE(selected_str);
943                 }
944                 return;
945         }
946         if (calculator_state == CALCULATOR_CALCULATED) {
947                 calculator_state = CALCULATOR_OPERATOR_INPUT;
948                 if (calculator_cursor_pos > strlen(calculator_input_str)) {
949                         calculator_cursor_pos = strlen(calculator_input_str);   /* set last position */
950                 }
951         }
952         _calc_entry_backspace(entry);
953         CALC_FUN_END();
954 }
955
956 static int __calculator_delete_long_press(void *data)
957 {
958         CALC_FUN_BEG();
959         Evas_Object *entry = (Evas_Object *) data;
960
961         if (calculator_state == CALCULATOR_CALCULATED) {
962                 calculator_state = CALCULATOR_OPERATOR_INPUT;
963                 if (calculator_cursor_pos > strlen(calculator_input_str)) {
964                         calculator_cursor_pos = strlen(calculator_input_str);   /* set last position */
965                 }
966         }
967         _calc_entry_backspace(entry);
968         CALC_FUN_END();
969         return 1;
970 }
971
972 /**
973 * @describe
974 *   Process +.-.*.\ these four buttons clicked.
975 *
976 * @param        entry
977 * @param        op_item
978 * @return       void
979 * @exception
980 */
981 static void
982 __calculator_control_normal_func_clicked(Evas *e,Evas_Object *entry,
983                                          op_item_t *op_item)
984 {
985         CALC_FUN_BEG();
986         if (select_mode) {
987                 char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
988                 if (selected_str) {
989                         if (calc_select_string_search(selected_str)) {
990                                 evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_sym, op_item->op_sym, 0, NULL);
991                         } else {
992                                 __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
993                                 calculator_cursor_pos = strlen(calculator_input_str);
994                         }
995                         SFREE(selected_str);
996                 }
997                 return;
998         }
999         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1000         strncpy(all_input, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
1001
1002         if (calculator_state == CALCULATOR_CALCULATED) {
1003                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1004                 char temp[20] = { 0 };
1005
1006                 calc_expr_num_format_result(last_result, temp);
1007                 _calc_entry_clear(entry);
1008                 //result < 0 or sicience number
1009                 if (temp[0] == '-' || strchr(temp, 'E')) {
1010                         _calc_entry_text_insert(entry, "(");
1011                         _calc_entry_text_insert(entry, temp);
1012                         _calc_entry_text_insert(entry, ")");
1013                 } else {
1014                         _calc_entry_text_insert(entry, temp);
1015                 }
1016
1017                 _calc_entry_text_insert(entry, op_item->op_sym);
1018                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1019                 return;
1020
1021         }
1022         if (!strcmp(op_item->op_sym, "x") ||!strcmp(op_item->op_sym, "/") ||!strcmp(op_item->op_sym, "+")) {
1023                 if (!__calculator_string_digit_in(calculator_input_str)) {
1024                         return;
1025                 }
1026         }
1027         int nCntOp = calc_expr_get_operator_num(all_input);
1028         if (nCntOp >= MAX_OPERATOR_NUM) {       /* Can't exceed 20 operators */
1029                 __calculator_wrong_format_create(CALC_MSG_MAX_OP);
1030                 return;
1031         }
1032
1033         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1034         int input_len = 0;
1035
1036         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1037         input_len = strlen(before_cursor);
1038
1039         if (input_len > 0) {
1040                 if (before_cursor[input_len - 1] == '(' && !strcmp(op_item->op_sym, "-")) {
1041                         _calc_entry_text_insert(entry, op_item->op_sym);
1042                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1043                 } else if (((input_len > 1) && (before_cursor[input_len - 1] == '-') && (before_cursor[input_len - 2] == '('))  //(-
1044                            || /*before_cursor[input_len - 1] == decimal_ch ||*/ before_cursor[input_len - 1] == '(')    // . or (
1045                 {
1046
1047                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1048                         return;
1049                 } else if (IS_OPERATOER(before_cursor[input_len - 1])) {
1050                         if ((input_len > 1 || !strcmp(op_item->op_sym, "-"))
1051                             || input_len == 1) {
1052                                 _calc_entry_backspace(entry);
1053                                 _calc_entry_text_insert(entry, op_item->op_sym);
1054                                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1055                         } else {
1056                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1057                         }
1058                         return;
1059                 } else if (before_cursor[input_len - 1] == ')') //
1060                 {
1061                         _calc_entry_text_insert(entry, op_item->op_sym);
1062                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1063                         return;
1064                 } else {
1065                         if (!IS_DIGITAL(before_cursor[input_len - 1])
1066                                         && (before_cursor[input_len - 1] != decimal_ch)) {
1067                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1068                                 return;
1069                         } else {
1070                                 _calc_entry_text_insert(entry, op_item->op_sym);
1071                                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1072                                 return;
1073                         }
1074                 }
1075         } else {                /* before_cursor si empty */
1076                 _calc_entry_text_insert(entry, op_item->op_sym);
1077                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1078         }
1079         CALC_FUN_END();
1080 }
1081
1082 /**
1083 * @describe
1084 *
1085 *
1086 * @param    entry
1087 * @return    void
1088 * @exception
1089 */
1090 static void __calculator_symbol_negative_clicked(Evas_Object * entry)
1091 {
1092         CALC_FUN_BEG();
1093
1094         char result[MAX_RESULT_LENGTH] = { 0 };
1095
1096         if (calculator_state == CALCULATOR_CALCULATED) {
1097                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1098
1099                 calc_expr_num_format_result(last_result, result);
1100                 if (last_result < 0) {
1101                         string_remove_at(result, 0, 1); //remove '-'
1102                 } else {
1103                         string_insert(result, 0, "(-"); // add (-xxx)
1104                         string_insert(result, strlen(result), ")");
1105                 }
1106
1107                 _calc_entry_clear(entry);
1108                 _calc_entry_text_insert(entry, result);
1109
1110                 calculator_state = CALCULATOR_OPERAND_INPUT;
1111                 //use_last_result = 1;
1112
1113                 return;
1114         }
1115
1116         int cursor = calculator_cursor_pos;
1117         int begin = 0, length = 0;
1118         char expr[MAX_EXPRESSION_LENGTH] = { 0 };
1119         strncpy(expr, calculator_input_str, MAX_EXPRESSION_LENGTH - 1);
1120         int flag = 0;
1121         cursor -= 1;
1122         if (expr[cursor] == ')') {
1123                 cursor -= 1;
1124                 flag = 1;       /* before current cursor is ')' */
1125         }
1126
1127         if (0 ==
1128             calc_expr_get_current_num_at_cursor(expr, cursor, &begin,
1129                                                 &length)) {
1130                 if (expr[begin] == '-') {
1131                         if (begin > 0 && expr[begin - 1] == '('
1132                             && expr[begin + length] == ')') {
1133                                 string_remove_at(expr, begin + length, 1);      //remove ')'
1134                                 string_remove_at(expr, begin - 1, 2);   // remove '(-'
1135                                 calculator_cursor_pos -= flag ? 3 : 2;
1136                         } else {
1137                                 string_remove_at(expr, begin, 1);
1138                                 calculator_cursor_pos -= 1;
1139                         }
1140
1141                 } else {
1142                         if (flag == 1)  //not '(-xxx)' but has ')'
1143                         {
1144                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1145                                 return;
1146                         } else {
1147                                 string_insert(expr, begin + length, ")");
1148                                 string_insert(expr, begin, "(-");
1149                                 calculator_cursor_pos +=
1150                                     (((begin + length) ==
1151                                       calculator_cursor_pos) ? 3 : 2);
1152                         }
1153                 }
1154                 strncpy(calculator_input_str, expr, MAX_EXPRESSION_LENGTH - 1);
1155
1156                 _calc_entry_text_set(entry, calculator_input_str);
1157                 _calc_entry_cursor_set(entry);
1158
1159                 calculator_state = CALCULATOR_OPERAND_INPUT;
1160
1161         } else {
1162                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1163         }
1164         CALC_FUN_END();
1165 }
1166
1167 /* search the previous operator and value */
1168 static char * __calculator_search_prev_input(char *input_str)
1169 {
1170         CALC_FUN_BEG();
1171         int i = 0;
1172         int bracket_number = 0;
1173         char *prev_input = NULL;
1174         for(; i< strlen(input_str); i++) {
1175                 if ('(' ==(input_str[i]) ){
1176                         bracket_number++;
1177                 }
1178                 if( ')' == input_str[i]){
1179                         bracket_number --;
1180                 }
1181                 if (CALCULATOR_CHAR_IS_PLUS_DEDUCT(input_str[i])
1182                         || CALCULATOR_CHAR_IS_MULTI_DIVIDE_OPERATOR(input_str[i])) {
1183                         if ( !bracket_number){
1184                                 prev_input = &input_str[i];
1185                                 return prev_input;
1186                         }
1187                 }
1188         }
1189         CALC_FUN_END();
1190         return prev_input;
1191 }
1192
1193 /**
1194 * @describe
1195 * Deal the event when "=" clicked on the keyboard
1196 *
1197 * @param[in]    entry   The input entry
1198 * @return               void
1199 * @exception
1200 */
1201 static void __calculator_op_equal(Evas_Object *entry)
1202 {
1203         CALC_FUN_BEG();
1204         if (entry == NULL) {
1205                 return;
1206         }
1207         if (calculator_state == CALCULATOR_CALCULATED) {
1208                 /*duplicate previous input operator and value*/
1209                 char *p = __calculator_search_prev_input(calculator_input_str);
1210                 if (p == NULL) {
1211                         return;
1212                 }
1213                 char prev_input[32] = { 0 };
1214                 int len = g_strlcpy(prev_input, p, sizeof(prev_input));
1215                 if (len >= sizeof(prev_input)) {
1216                         return;
1217                 }
1218                 char temp[32] = { 0 };
1219                 calc_expr_num_format_result(last_result, temp);
1220                 _calc_entry_clear(entry);
1221
1222                 if (temp[0] == '-' || strchr(temp, 'E')) {
1223                         _calc_entry_text_insert(entry, "(");
1224                         _calc_entry_text_insert(entry, temp);
1225                         _calc_entry_text_insert(entry, ")");
1226                 } else {
1227                         _calc_entry_text_insert(entry, temp);
1228                 }
1229                 _calc_entry_text_insert(entry, prev_input);
1230                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1231         }
1232
1233         double result = 0;
1234         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1235         char result_buf[MAX_RESULT_LENGTH] = { 0 };
1236         char result_format[MAX_RESULT_LENGTH] = { 0 };
1237         int str_len = 0;
1238         char error_msg[MAX_ERROR_MESSAGE_LENGTH] = { 0 };
1239         calc_expr_close_parentheses(calculator_input_str);
1240         _calc_entry_text_set(entry, calculator_input_str);
1241         snprintf(str_buf, sizeof(str_buf), "%s", calculator_input_str);
1242         str_len = strlen(str_buf);
1243         if (str_len == 0) {
1244                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1245                 return;
1246         }
1247
1248         if (!calculator_calculate(str_buf, &result, error_msg)) {
1249                 __calculator_wrong_format_create(error_msg);
1250                 calculator_state = CALCULATOR_ERROR_OCCURED;
1251                 return;
1252         } else {
1253                 last_result = result;
1254                 memset(result_buf, 0, CALCULATOR_CONTENT_LEN + 1);
1255                 calc_expr_num_format_result(result, result_buf);
1256                 /* save result */
1257
1258                 struct history_item item;
1259                 memset(item.expression, 0, sizeof(item.expression));
1260                 memset(result_format, 0, sizeof(result_format));
1261                 calc_expr_format_expression(calculator_input_str,
1262                                             item.expression);
1263                 item.result = result;
1264                 calc_expr_format_expression(result_buf, result_format);
1265                 if (result_buf[0] == '-') {
1266                         string_replace(result_format, "\xe2\x88\x92", "-");
1267                 }
1268 #ifdef SAVE_HISTORY
1269                 calc_view_save_history(&item);
1270 #endif
1271                 /* show result */
1272                 calculator_state = CALCULATOR_CALCULATED;
1273                 calc_view_show_result(result_format, ad);
1274
1275         }
1276         CALC_FUN_END();
1277 }
1278
1279 /**
1280 * @describe
1281 *
1282 *
1283 * @param        entry
1284 * @return       void
1285 * @exception    none
1286 */
1287 static void __calculator_parenthesis_clicked(Evas_Object * entry)
1288 {
1289         CALC_FUN_BEG();
1290         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1291         snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1292         if (calculator_state == CALCULATOR_CALCULATED) {
1293                 edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1294
1295                 char temp[MAX_RESULT_LENGTH] = { 0 };
1296
1297                 calc_expr_num_format_result(last_result, temp);
1298                 _calc_entry_clear(entry);
1299
1300                 if (temp[0] == '-' || strchr(temp, 'E') != NULL)        //result < 0 or science number
1301                 {
1302                         _calc_entry_text_insert(entry, "((");
1303                         _calc_entry_text_insert(entry, temp);
1304                         _calc_entry_text_insert(entry, ")");
1305                 } else {
1306                         _calc_entry_text_insert(entry, "(");
1307                         _calc_entry_text_insert(entry, temp);
1308                 }
1309                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1310                 return;
1311         }
1312         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1313         int input_len = 0;
1314         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1315         input_len = strlen(before_cursor);
1316
1317         if (input_len == 0) {
1318                 _calc_entry_text_insert(entry, "(");
1319                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1320                 return;
1321         }
1322         int bracket_num = calculator_get_open_braket(all_input);
1323         if (input_len > 0) {
1324                 if (before_cursor[input_len - 1] == decimal_ch) {
1325                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1326                         return;
1327                 } else if (bracket_num > 0      //'(' is more than ')'
1328                            && before_cursor[input_len - 1] != '('
1329                            && (before_cursor[input_len - 1] == ')'
1330                                || isdigit(before_cursor[input_len - 1])
1331                                ||
1332                                (__calculator_string_get_char_type
1333                                 (before_cursor[input_len - 1]) == CHAR_IS_PI
1334                                 ||
1335                                 __calculator_string_get_char_type
1336                                 (before_cursor[input_len - 1]) == CHAR_IS_E))) {
1337                         _calc_entry_text_insert(entry, ")");
1338                         return;
1339                 } else if (bracket_num == 0) {
1340                         if (calc_expr_get_left_parentheses_num
1341                             (calculator_input_str) < MAX_PARENTHESES_NUM) {
1342                                 _calc_entry_text_insert(entry, "(");
1343                         }
1344                         return;
1345                 } else if (before_cursor[input_len - 1] != ')') //'(' is less than ')'!isdigit(before_cursor[input_len-1])&&(
1346                 {
1347                         if (calc_expr_get_left_parentheses_num
1348                             (calculator_input_str) < MAX_PARENTHESES_NUM) {
1349                                 _calc_entry_text_insert(entry, "(");
1350                         }
1351                         return;
1352                 }
1353         }
1354         CALC_FUN_END();
1355         return;
1356 }
1357
1358 /**
1359 * @describe
1360 *
1361 *
1362 * @param        entry
1363 * @param        op_item
1364 * @return       void
1365 * @exception
1366 */
1367 static void
1368 __calculator_control_functions_button_clicked(Evas *e, Evas_Object *entry, op_item_t *op_item)
1369 {
1370         CALC_FUN_BEG();
1371
1372         char *str = NULL;
1373         function_t function = { 0 };
1374
1375         memset(&function, 0x0, sizeof(function_t));
1376         str = op_item->op_name;
1377
1378         char all_input[MAX_EXPRESSION_LENGTH] = { 0 };
1379         int input_len = 0;
1380         char before_cursor[MAX_EXPRESSION_LENGTH] = { 0 };
1381         int before_len = 0;
1382         last_char_t last_char_type = 0;
1383
1384         snprintf(all_input, sizeof(all_input), "%s", calculator_input_str);
1385         __calculator_get_input_from_begin_to_cursor(all_input, before_cursor);
1386         input_len = strlen(all_input);
1387         before_len = strlen(before_cursor);
1388         if(before_len > 0){
1389                 last_char_type = __calculator_string_get_char_type(before_cursor[before_len - 1]);
1390         }
1391
1392         switch (op_item->op_id) {
1393         case OP_PERCENT:
1394                 if (select_mode) {
1395                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1396                         calculator_cursor_pos = strlen(calculator_input_str);
1397                         return;
1398                 }
1399                 /* if it is calculated state */
1400                 if (calculator_state == CALCULATOR_CALCULATED) {
1401                         edje_object_signal_emit(_EDJ(ad->edje), "show,input","");
1402
1403                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1404                         double per_result = last_result / 100.0;
1405
1406                         calc_expr_num_format_result(per_result, temp);
1407                         _calc_entry_clear(entry);
1408
1409                         if (strcmp(temp, "0") == 0) {
1410                                 _calc_entry_text_insert(entry, "0");
1411                         } else if (temp[0] == '-')      //result < 0
1412                         {
1413                                 _calc_entry_text_insert(entry, "(");
1414                                 _calc_entry_text_insert(entry, temp);
1415                                 _calc_entry_text_insert(entry, ")");
1416                         } else {
1417                                 _calc_entry_text_insert(entry, temp);
1418                         }
1419                         calculator_state = CALCULATOR_OPERAND_INPUT;
1420                         return;
1421                 }
1422
1423                 {
1424                         int from_pos, end_pos;
1425                         char str_num[CALCULATOR_CONTENT_LEN] = { 0 };
1426                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1427                         double per_result = 0.0;
1428
1429                         if (false ==  __calculator_get_cursor_position_float_string(all_input, str_num, calculator_cursor_pos, &from_pos, &end_pos)) {
1430                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1431                                 calculator_cursor_pos = strlen(calculator_input_str);
1432                                 return;
1433                         }
1434
1435                         {
1436                                 if (strlen(str_num) == 0) {
1437                                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1438                                         return;
1439                                 }
1440
1441                                 if (strcmp(str_num, "0") == 0) {
1442                                         return;
1443                                 }
1444
1445                                 per_result = atof(str_num);
1446                                 per_result /= 100.0;
1447
1448                                 calc_expr_num_format_result(per_result, temp);
1449
1450                                 _calc_entry_text_remove(entry, from_pos, end_pos);
1451                                 _calc_entry_text_insert(entry, temp);
1452
1453                                 calculator_state = CALCULATOR_OPERAND_INPUT;
1454                                 return;
1455                         }
1456                 }
1457                 break;
1458         case OP_PI:
1459                 if (select_mode) {
1460                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1461                         calculator_cursor_pos = strlen(calculator_input_str);
1462                         return;
1463                 }
1464                 if (calculator_state == CALCULATOR_CALCULATED) {
1465                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1466                                                 "");
1467                         _calc_entry_clear(entry);
1468                         _calc_entry_text_insert(entry, op_item->op_name);
1469                         break;
1470                 }
1471                 if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
1472                     && (!IS_OPERATOER(before_cursor[before_len - 1]))
1473                     && (before_cursor[before_len - 1] != '(')
1474                     && (before_cursor[before_len - 1] != 'P')
1475                     && before_cursor[before_len - 1] != 'C') {
1476                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1477                         break;
1478                 }
1479                 /* input digital after "p", the "x" opeartor will be added automatically */
1480                 if(IS_DIGITAL(before_cursor[before_len - 1])){
1481                         _calc_entry_text_insert(entry, "x");
1482                 }
1483                 _calc_entry_text_insert(entry, op_item->op_name);
1484                 break;
1485
1486         case OP_E:
1487                 if (select_mode) {
1488                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1489                         calculator_cursor_pos = strlen(calculator_input_str);
1490                         return;
1491                 }
1492                 if (calculator_state == CALCULATOR_CALCULATED) {
1493                         edje_object_signal_emit(_EDJ(ad->edje), "show,input","");
1494                         _calc_entry_clear(entry);
1495                         _calc_entry_text_insert(entry, op_item->op_name);
1496                         break;
1497                 }
1498                 if ((before_len != 0) && (!IS_DIGITAL(before_cursor[before_len - 1]))
1499                     && (!IS_OPERATOER(before_cursor[before_len - 1]))
1500                     && (before_cursor[before_len - 1] != '(')
1501                     && (before_cursor[before_len - 1] != 'P')
1502                     && before_cursor[before_len - 1] != 'C') {
1503                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1504                         break;
1505                 }
1506                 /* input digital after "e", the "x" opeartor will be added automatically */
1507                 if(IS_DIGITAL(before_cursor[before_len - 1])){
1508                         _calc_entry_text_insert(entry, "x");
1509                 }
1510                 _calc_entry_text_insert(entry, op_item->op_name);
1511                 break;
1512
1513         case OP_SIN:            //sin()
1514         case OP_COS:            //cos()
1515         case OP_TAN:            //tan()
1516         case OP_LOG:            //log()
1517         case OP_ABS:            //abs()
1518                 if (select_mode) {
1519                         char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1520                         if (selected_str) {
1521                                 if (calc_select_string_search(selected_str)) {
1522                                         evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym,
1523                                                 op_item->op_name, op_item->op_sym, 0, NULL);
1524                                 } else {
1525                                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1526                                         calculator_cursor_pos = strlen(calculator_input_str);
1527                                 }
1528                                 SFREE(selected_str);
1529                         }
1530                         return;
1531                 }
1532                 if (calculator_state == CALCULATOR_CALCULATED) {
1533                         edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1534
1535                         _calc_entry_clear(entry);
1536                         _calc_entry_text_insert(entry, op_item->op_name);
1537                         break;
1538                 }
1539                 if (last_char_type == CHAR_IS_PI || last_char_type == CHAR_IS_E) {
1540                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1541                         break;
1542                 }
1543
1544                 _calc_entry_text_insert(entry, op_item->op_name);
1545                 break;
1546
1547         case OP_LN:             //ln()
1548                 if (select_mode) {
1549                         char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1550                         if (selected_str) {
1551                                 if (calc_select_string_search(selected_str)) {
1552                                         evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_name,
1553                                                 op_item->op_sym, 0, NULL);
1554                                 } else {
1555                                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1556                                         calculator_cursor_pos = strlen(calculator_input_str);
1557                                 }
1558                                 SFREE(selected_str);
1559                         }
1560                         return;
1561                 }
1562                 if (calculator_state == CALCULATOR_CALCULATED) {
1563                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1564                                                 "");
1565                         _calc_entry_clear(entry);
1566                         _calc_entry_text_insert(entry, op_item->op_name);
1567                         break;
1568                 }
1569                 if (last_char_type == CHAR_IS_PI) {
1570                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1571                         break;
1572                 }
1573                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1574                     && (before_cursor[before_len - 1] != '-')
1575                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1576                     && (before_cursor[before_len - 1] != '^')
1577                     && (before_cursor[before_len - 1] != '(')
1578                     && (before_cursor[before_len - 1] != 'C')
1579                     && (before_cursor[before_len - 1] != 'P')) {
1580                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1581                         break;
1582                 }
1583                 _calc_entry_text_insert(entry, op_item->op_name);
1584                 break;
1585
1586         case OP_ROOT:           //sqrt()
1587                 if (select_mode) {
1588                         char *selected_str = elm_entry_markup_to_utf8(elm_entry_selection_get(entry));
1589                         if (selected_str) {
1590                                 if (calc_select_string_search(selected_str)) {
1591                                         evas_event_feed_key_down(e, op_item->op_sym, op_item->op_sym, op_item->op_name,
1592                                                 op_item->op_sym, 0, NULL);
1593                                 } else {
1594                                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1595                                         calculator_cursor_pos = strlen(calculator_input_str);
1596                                 }
1597                                 SFREE(selected_str);
1598                         }
1599                         return;
1600                 }
1601                 if (calculator_state == CALCULATOR_CALCULATED) {
1602                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1603                                                 "");
1604
1605                         _calc_entry_clear(entry);
1606                         _calc_entry_text_insert(entry, op_item->op_name);
1607                         break;
1608                 }
1609                 if (last_char_type == CHAR_IS_PI) {
1610                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1611                         break;
1612                 }
1613                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1614                     && (before_cursor[before_len - 1] != '-')
1615                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1616                     && (before_cursor[before_len - 1] != '^')
1617                     && (before_cursor[before_len - 1] != '(')
1618                     && (before_cursor[before_len - 1] != 'C')
1619                     && (before_cursor[before_len - 1] != 'P')) {
1620                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1621                         break;
1622                 }
1623                 _calc_entry_text_insert(entry, op_item->op_name);
1624                 break;
1625
1626         case OP_10X:            //10^
1627                 if (calculator_state == CALCULATOR_CALCULATED) {
1628                         edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1629                         _calc_entry_clear(entry);
1630                         _calc_entry_text_insert(entry, op_item->op_name);
1631                         break;
1632                 }
1633                 if (last_char_type == CHAR_IS_PI) {
1634                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1635                         break;
1636                 }
1637                 if ((before_len != 0) && (before_cursor[before_len - 1] != '+')
1638                     && (before_cursor[before_len - 1] != '-')
1639                     && (last_char_type != CHAR_IS_MULTIPLY_DIVIDE)
1640                     && (before_cursor[before_len - 1] != '^')
1641                     && (before_cursor[before_len - 1] != '(')
1642                     && (before_cursor[before_len - 1] != 'C')
1643                     && (before_cursor[before_len - 1] != 'P')) {
1644                         __calculator_wrong_format_create(CALC_MSG_OP_FIRST);
1645                         break;
1646                 }
1647                 _calc_entry_text_insert(entry, op_item->op_name);
1648                 break;
1649
1650         case OP_X2:             //x^2
1651                 if (calculator_state == CALCULATOR_CALCULATED) {
1652                         edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
1653
1654                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1655                         calc_expr_num_format_result(last_result, temp);
1656                         _calc_entry_clear(entry);
1657
1658                         if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or science number
1659                         {
1660                                 _calc_entry_text_insert(entry, "(");
1661                                 _calc_entry_text_insert(entry, temp);
1662                                 _calc_entry_text_insert(entry, ")");
1663                         } else {
1664                                 _calc_entry_text_insert(entry, temp);
1665                         }
1666                         _calc_entry_text_insert(entry, op_item->op_name);
1667                         calculator_state = CALCULATOR_OPERAND_INPUT;
1668                         //use_last_result = 1;
1669                         return;
1670                 }
1671
1672                 if (input_len == 0) {
1673                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1674                         break;
1675                 }
1676                 if (last_char_type == CHAR_IS_PI) {
1677                         _calc_entry_text_insert(entry, op_item->op_name);
1678                         calculator_state = CALCULATOR_OPERAND_INPUT;
1679                         break;
1680                 } else if ((before_len > 0)
1681                            && (!isdigit(before_cursor[before_len - 1]))
1682                            && (before_cursor[before_len - 1] != ')')) {
1683                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_X2);
1684                         break;
1685                 }
1686                 _calc_entry_text_insert(entry, op_item->op_name);
1687                 calculator_state = CALCULATOR_OPERAND_INPUT;
1688                 break;
1689         case OP_XY:             //x^y
1690                 if (calculator_state == CALCULATOR_CALCULATED) {
1691                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1692                                                 "");
1693
1694                         char temp[CALCULATOR_CONTENT_LEN] = { 0 };
1695
1696                         calc_expr_num_format_result(last_result, temp);
1697                         _calc_entry_clear(entry);
1698
1699                         if (temp[0] == '-' || strchr(temp, 'E'))        //result < 0 or science number
1700                         {
1701                                 _calc_entry_text_insert(entry, "(");
1702                                 _calc_entry_text_insert(entry, temp);
1703                                 _calc_entry_text_insert(entry, ")");
1704                         } else {
1705                                 _calc_entry_text_insert(entry, temp);
1706                         }
1707                         _calc_entry_text_insert(entry, op_item->op_name);
1708                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1709                         return;
1710                 }
1711
1712                 if (input_len == 0) {
1713                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1714                         break;
1715                 }
1716                 if ((last_char_type == CHAR_IS_PI)
1717                     || (last_char_type == CHAR_IS_E)) {
1718                         _calc_entry_text_insert(entry, op_item->op_name);
1719                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1720                         break;
1721                 } else if ((before_len > 0)
1722                            && !isdigit(before_cursor[before_len - 1])
1723                            && (before_cursor[before_len - 1] != ')')) {
1724                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_XY);
1725                         break;
1726                 }
1727                 _calc_entry_text_insert(entry, op_item->op_name);
1728                 calculator_state = CALCULATOR_OPERATOR_INPUT;
1729                 break;
1730
1731         case OP_FACT:           //x!
1732                 if (select_mode) {
1733                         __calculator_wrong_format_create(CALC_MSG_WRONG_FORMAT);
1734                         calculator_cursor_pos = strlen(calculator_input_str);
1735                         return;
1736                 }
1737                 if (calculator_state == CALCULATOR_CALCULATED) {
1738                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1739                                                 "");
1740
1741                         char temp[MAX_RESULT_LENGTH] = { 0 };
1742
1743                         calc_expr_num_format_result(last_result, temp);
1744
1745                         if (strchr(temp, decimal_ch) != NULL || strchr(temp, '-') != NULL)      //revise by bfl
1746                         {
1747                                 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1748                                 calculator_state = CALCULATOR_WAITING_INPUT;    //revise by bfl
1749                                 return;
1750                         }
1751
1752                         _calc_entry_clear(entry);
1753                         _calc_entry_text_insert(entry, "(");
1754                         _calc_entry_text_insert(entry, temp);
1755                         _calc_entry_text_insert(entry, "!)");
1756
1757                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1758                         return;
1759                 }
1760
1761                 if (input_len == 0) {
1762                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_FAC);
1763                         break;
1764                 }
1765                 if ((last_char_type == CHAR_IS_PI)
1766                     || (last_char_type == CHAR_IS_E)) {
1767                         __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1768                         break;
1769                 }
1770
1771                 /* check if it is natural */
1772                 {
1773                         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1774                         int from_pos = 0, end_pos = 0;
1775
1776                         if (false ==
1777                             __calculator_get_cursor_position_float_string
1778                             (all_input, str_buf, calculator_cursor_pos,
1779                              &from_pos, &end_pos)) {
1780                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST);
1781                                 break;
1782                         }
1783
1784                         if (strchr(str_buf, decimal_ch) != NULL
1785                             || str_buf[0] == '-') {
1786                                 __calculator_wrong_format_create(CALC_MSG_INVALID_FAC);
1787                                 break;
1788                         }
1789
1790                         _calc_entry_text_remove(entry, from_pos, end_pos);
1791                         _calc_entry_text_insert(entry, "(");
1792                         _calc_entry_text_insert(entry, str_buf);
1793                         _calc_entry_text_insert(entry, "!)");
1794                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1795                 }
1796                 break;
1797         case OP_1X:
1798                 if (calculator_state == CALCULATOR_CALCULATED) {
1799                         edje_object_signal_emit(_EDJ(ad->edje), "show,input",
1800                                                 "");
1801
1802                         char temp[MAX_RESULT_LENGTH] = { 0 };
1803                         int i = 0;
1804
1805                         calc_expr_num_format_result(last_result, temp);
1806                         if (strchr(temp, 'E') != NULL)  //science number
1807                         {
1808                                 temp[strlen(temp)] = ')';
1809                                 for (i = strlen(temp); i > 0; --i) {
1810                                         temp[i] = temp[i - 1];
1811                                 }
1812                                 temp[0] = '(';
1813                         }
1814
1815                         _calc_entry_clear(entry);
1816                         if (temp[0] == '-') {
1817                                 _calc_entry_text_insert(entry, "(-1");
1818                                 _calc_entry_text_insert(entry, "/");
1819
1820                                 _calc_entry_text_insert(entry, &temp[1]);
1821                                 _calc_entry_text_insert(entry, ")");
1822                         } else {
1823                                 _calc_entry_text_insert(entry, "(1");
1824                                 _calc_entry_text_insert(entry, "/");
1825
1826                                 _calc_entry_text_insert(entry, temp);
1827                                 _calc_entry_text_insert(entry, ")");
1828                         }
1829
1830                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1831                         //use_last_result = 1;
1832                         return;
1833                 }
1834                 if (input_len == 0) {
1835                         __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1836                         break;
1837                 }
1838
1839                 /* check if it is digit */
1840                 {
1841                         char str_buf[MAX_EXPRESSION_LENGTH] = { 0 };
1842                         int from_pos = 0, end_pos = 0;
1843
1844                         if (false ==
1845                             __calculator_get_cursor_position_float_string
1846                             (all_input, str_buf, calculator_cursor_pos,
1847                              &from_pos, &end_pos)) {
1848                                 __calculator_wrong_format_create(CALC_MSG_NUM_FIRST_RECIP);
1849                                 break;
1850                         }
1851
1852                         if (strcmp(str_buf, "p") && strcmp(str_buf, "e")
1853                             && atof(str_buf) == 0) {
1854                                 __calculator_wrong_format_create(CALC_MSG_DIVIDE_BY_ZERO);
1855                                 break;
1856                         }
1857
1858                         _calc_entry_text_remove(entry, from_pos, end_pos);
1859                         if (str_buf[0] == '-') {
1860                                 _calc_entry_text_insert(entry, "(-1");
1861                                 _calc_entry_text_insert(entry, "/");
1862
1863                                 _calc_entry_text_insert(entry, &str_buf[1]);
1864                                 _calc_entry_text_insert(entry, ")");
1865                         } else {
1866                                 _calc_entry_text_insert(entry, "(1");
1867                                 _calc_entry_text_insert(entry, "/");
1868
1869                                 _calc_entry_text_insert(entry, str_buf);
1870                                 _calc_entry_text_insert(entry, ")");
1871                         }
1872
1873                         calculator_state = CALCULATOR_OPERATOR_INPUT;
1874                 }
1875                 break;
1876
1877         default:
1878                 break;
1879         }
1880         calculator_state = CALCULATOR_SPECIAL_FUNCTION_INPUT;
1881         CALC_FUN_END();
1882         return;
1883 }
1884
1885 /////////////////////////// input text finish ////////////////////////////
1886
1887 /**
1888 * @describe
1889 *
1890 *
1891 * @param    evas_obj
1892 * @param    obj
1893 * @return    void
1894 * @exception
1895 */
1896 static int _calculator_get_input_item(Evas_Object * evas_obj, Evas_Object * obj)
1897 {
1898         CALC_FUN_BEG();
1899
1900         int val = 0;
1901         if (evas_obj == edje_object_part_object_get(obj, "item_brack")) {
1902                 val = OP_PARENTHESIS;
1903         } else if (evas_obj == edje_object_part_object_get(obj, "item_del")) {
1904                 val = OP_DELETE;
1905         } else if (evas_obj == edje_object_part_object_get(obj, "item_c")) {
1906                 val = OP_CLEAR;
1907         } else if (evas_obj == edje_object_part_object_get(obj, "item_div")) {
1908                 val = OP_DIVIDE;
1909         } else if (evas_obj == edje_object_part_object_get(obj, "item_num7")) {
1910                 val = OP_NUM_7;
1911         } else if (evas_obj == edje_object_part_object_get(obj, "item_num8")) {
1912                 val = OP_NUM_8;
1913         } else if (evas_obj == edje_object_part_object_get(obj, "item_num9")) {
1914                 val = OP_NUM_9;
1915         } else if (evas_obj == edje_object_part_object_get(obj, "item_mul")) {
1916                 val = OP_MULTIPLY;
1917         } else if (evas_obj == edje_object_part_object_get(obj, "item_num4")) {
1918                 val = OP_NUM_4;
1919         } else if (evas_obj == edje_object_part_object_get(obj, "item_num5")) {
1920                 val = OP_NUM_5;
1921         } else if (evas_obj == edje_object_part_object_get(obj, "item_num6")) {
1922                 val = OP_NUM_6;
1923         } else if (evas_obj == edje_object_part_object_get(obj, "item_sub")) {
1924                 val = OP_MINUS;
1925         } else if (evas_obj == edje_object_part_object_get(obj, "item_num1")) {
1926                 val = OP_NUM_1;
1927         } else if (evas_obj == edje_object_part_object_get(obj, "item_num2")) {
1928                 val = OP_NUM_2;
1929         } else if (evas_obj == edje_object_part_object_get(obj, "item_num3")) {
1930                 val = OP_NUM_3;
1931         } else if (evas_obj == edje_object_part_object_get(obj, "item_plus")) {
1932                 val = OP_PLUS;
1933         } else if (evas_obj == edje_object_part_object_get(obj, "item_dot")) {
1934                 val = OP_DOT;
1935         } else if (evas_obj == edje_object_part_object_get(obj, "item_num0")) {
1936                 val = OP_NUM_0;
1937         } else if (evas_obj == edje_object_part_object_get(obj, "item_neg")) {
1938                 val = OP_PLUS_MINUS;
1939         } else if (evas_obj == edje_object_part_object_get(obj, "item_eq")) {
1940                 val = OP_EQUAL;
1941         } else if (evas_obj == edje_object_part_object_get(obj, "item_per")) {
1942                 val = OP_PERCENT;
1943         } else if (evas_obj == edje_object_part_object_get(obj, "item_sqr")) {
1944                 val = OP_ROOT;
1945         } else if (evas_obj == edje_object_part_object_get(obj, "item_fac")) {
1946                 val = OP_FACT;
1947         } else if (evas_obj == edje_object_part_object_get(obj, "item_sin")) {
1948                 val = OP_SIN;
1949         } else if (evas_obj == edje_object_part_object_get(obj, "item_cos")) {
1950                 val = OP_COS;
1951         } else if (evas_obj == edje_object_part_object_get(obj, "item_tan")) {
1952                 val = OP_TAN;
1953         } else if (evas_obj == edje_object_part_object_get(obj, "item_ln")) {
1954                 val = OP_LN;
1955         } else if (evas_obj == edje_object_part_object_get(obj, "item_log")) {
1956                 val = OP_LOG;
1957         } else if (evas_obj == edje_object_part_object_get(obj, "item_1x")) {
1958                 val = OP_1X;
1959         } else if (evas_obj == edje_object_part_object_get(obj, "item_10x")) {
1960                 val = OP_10X;
1961         } else if (evas_obj == edje_object_part_object_get(obj, "item_x2")) {
1962                 val = OP_X2;
1963         } else if (evas_obj == edje_object_part_object_get(obj, "item_xy")) {
1964                 val = OP_XY;
1965         } else if (evas_obj == edje_object_part_object_get(obj, "item_abs")) {
1966                 val = OP_ABS;
1967         } else if (evas_obj == edje_object_part_object_get(obj, "item_pi")) {
1968                 val = OP_PI;
1969         } else if (evas_obj == edje_object_part_object_get(obj, "item_e")) {
1970                 val = OP_E;
1971         }
1972         CALC_FUN_END();
1973         return val;
1974 }
1975
1976 /////////////////////////// input text finish ////////////////////////////
1977
1978 #ifdef __i386__
1979 /**
1980 * @describe
1981 *
1982 *
1983 * @param    evas_obj
1984 * @param    obj
1985 * @return    void
1986 * @exception
1987 */
1988 static int _calculator_get_input_item_hd(const char *keyname, Evas_Object * obj)
1989 {
1990         CALC_FUN_BEG();
1991         int val = 0;
1992         if (0 == strcmp(keyname, "KP_7")) {
1993                 val = OP_NUM_7;
1994         } else if (0 == strcmp(keyname, "KP_8")) {
1995                 val = OP_NUM_8;
1996         } else if (0 == strcmp(keyname, "KP_9")) {
1997                 val = OP_NUM_9;
1998         } else if (0 == strcmp(keyname, "KP_4")) {
1999                 val = OP_NUM_4;
2000         } else if (0 == strcmp(keyname, "KP_5")) {
2001                 val = OP_NUM_5;
2002         } else if (0 == strcmp(keyname, "KP_6")) {
2003                 val = OP_NUM_6;
2004         } else if (0 == strcmp(keyname, "KP_1")) {
2005                 val = OP_NUM_1;
2006         } else if (0 == strcmp(keyname, "KP_2")) {
2007                 val = OP_NUM_2;
2008         } else if (0 == strcmp(keyname, "KP_3")) {
2009                 val = OP_NUM_3;
2010         } else if (0 == strcmp(keyname, "KP_0")) {
2011                 val = OP_NUM_0;
2012         }else if (0 == strcmp(keyname, "KP_Decimal")) {
2013                 val = OP_DOT;
2014         } else if (0 == strcmp(keyname, "Return")) {
2015                 val = OP_EQUAL;
2016         } else if (0 == strcmp(keyname, "KP_Add")) {
2017                 val = OP_PLUS;
2018         } else if (0 == strcmp(keyname, "KP_Subtract")) {
2019                 val = OP_MINUS;
2020         } else if (0 == strcmp(keyname, "minus")) {
2021                 val = OP_MINUS;
2022         } else if (0 == strcmp(keyname, "KP_Multiply")) {
2023                 val = OP_MULTIPLY;
2024         } else if (0 == strcmp(keyname, "slash")) {
2025                 val = OP_DIVIDE;
2026         } else if (0 == strcmp(keyname, "KP_Divide")) {
2027                 val = OP_DIVIDE;
2028         }else if (0 == strcmp(keyname, "BackSpace")) {
2029                 val = OP_DELETE;
2030         }
2031         CALC_FUN_END();
2032         return val;
2033 }
2034 #endif
2035
2036 /**
2037 * @description
2038 *   Interpret all of our different signals, and do things !
2039 *
2040 * @param        data
2041 * @param        e
2042 * @param        evas_obj
2043 * @param        event_info
2044 * @return       void
2045 * @exception    none
2046 */
2047 static void
2048 _calculator_interp(void *data, Evas * e, Evas_Object * evas_obj, void *event_info)
2049 {
2050
2051         CALC_FUN_BEG();
2052         int val = 0;
2053         if (data) {
2054
2055                 Evas_Object *obj = (Evas_Object *) data;
2056                 val = _calculator_get_input_item(evas_obj, obj);
2057                 if (ad->wrong_timer) {
2058                         ecore_timer_del(ad->wrong_timer);
2059                         ad->wrong_timer = NULL;
2060                 }
2061                 switch (val) {
2062                 case OP_DELETE:
2063                         _calc_btn_backspace_clicked(e, ad->input_entry);
2064                         if (ad->calc_timer) {
2065                                 ecore_timer_del(ad->calc_timer);
2066                                 ad->calc_timer = NULL;
2067                         }
2068                         ad->calc_timer =
2069                             ecore_timer_add(0.1, (Ecore_Task_Cb)__calculator_delete_long_press, ad->input_entry);
2070                         break;
2071                 case OP_CLEAR:
2072                         edje_object_signal_emit(_EDJ(ad->edje), "show,input", "");
2073                         _calc_entry_clear(ad->input_entry);
2074                         calculator_state = CALCULATOR_WAITING_INPUT;
2075                         break;
2076                 case OP_PLUS:
2077                 case OP_MINUS:
2078                 case OP_MULTIPLY:
2079                 case OP_DIVIDE:
2080                         __calculator_control_normal_func_clicked(e, ad->input_entry, &calc_op_item[val]);
2081                         break;
2082                 case OP_DOT:
2083                         _calc_btn_dot_clicked(ad->input_entry);
2084                         break;
2085                 case OP_PARENTHESIS:
2086                         __calculator_parenthesis_clicked(ad->input_entry);
2087                         break;
2088                 case OP_EQUAL:
2089                         __calculator_op_equal(ad->input_entry);
2090                         break;
2091                 case OP_NUM_0:
2092                 case OP_NUM_1:
2093                 case OP_NUM_2:
2094                 case OP_NUM_3:
2095                 case OP_NUM_4:
2096                 case OP_NUM_5:
2097                 case OP_NUM_6:
2098                 case OP_NUM_7:
2099                 case OP_NUM_8:
2100                 case OP_NUM_9:
2101                         __calculator_control_panel_number_button_clicked(e, ad->input_entry, &calc_op_item[val]);
2102                         break;
2103                 case OP_PLUS_MINUS:
2104                         __calculator_symbol_negative_clicked(ad->input_entry);
2105                         break;
2106                 case OP_PERCENT...OP_E:
2107                         __calculator_control_functions_button_clicked(e, ad->input_entry, &calc_op_item[val]);
2108                         break;
2109                 default:
2110                         break;
2111                 }
2112                 if (val == OP_DELETE) {
2113                         feedback_play(FEEDBACK_PATTERN_SIP_BACKSPACE);
2114                 } else {
2115                         feedback_play(FEEDBACK_PATTERN_SIP);
2116                 }
2117         }
2118
2119         CALC_FUN_END();
2120 }
2121
2122 static void __calculator_wrong_format_delete(Evas_Object *in_entry)
2123 {
2124         _calc_entry_text_set(in_entry, calculator_input_str);
2125         if (ad->wrong_timer) {
2126                 ecore_timer_del(ad->wrong_timer);
2127                 ad->wrong_timer = NULL;
2128         }
2129 }
2130
2131 static void __calculator_wrong_text_set(char * wrong_string)
2132 {
2133         char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2134         int fontsize = 50;
2135         memset(buf, 0, sizeof(buf));
2136         snprintf(buf, sizeof(buf),
2137                  "<align=right><+ font_size=%d><color=#855B11FF>%s",
2138                  fontsize, wrong_string);
2139         elm_entry_editable_set(ad->input_entry, EINA_FALSE);//chx add avoid the word splited
2140         elm_entry_line_wrap_set(ad->input_entry,ELM_WRAP_MIXED);
2141         elm_entry_input_panel_enabled_set(ad->input_entry, EINA_FALSE);
2142         elm_entry_entry_set(ad->input_entry, buf);
2143         elm_entry_cursor_end_set(ad->input_entry);
2144         elm_object_focus_set(ad->input_entry, EINA_TRUE);
2145         calc_view_revise_input_scroller(ad);
2146 }
2147
2148 /**
2149 * @describe
2150 *
2151 *
2152 * @param        msg
2153 * @return       void
2154 * @exception    none
2155 */
2156 static void __calculator_wrong_format_create(char * wrong_string)
2157 {
2158         __calculator_wrong_text_set(wrong_string);
2159         if (ad->wrong_timer) {
2160                 ecore_timer_del(ad->wrong_timer);
2161                 ad->wrong_timer = NULL;
2162         }
2163         ad->wrong_timer = ecore_timer_add(3, (Ecore_Task_Cb)__calculator_wrong_format_delete, ad->input_entry);
2164 }
2165
2166 /* mouse up for delete button. */
2167 static void
2168 __calculator_delelte_up(void *data, Evas * e, Evas_Object * evas_obj,
2169                         void *event_info)
2170 {
2171         CALC_FUN_BEG();
2172         if (ad->calc_timer) {
2173                 ecore_timer_del(ad->calc_timer);
2174                 ad->calc_timer = NULL;
2175         }
2176         CALC_FUN_END();
2177 }
2178
2179 /**
2180 * @describe
2181 *   Register clicked callback of the keys on the keypad.
2182 *
2183 * @param    keypad      the keypad
2184 * @return   void
2185 */
2186 void _calc_view_keypad_cb_register(Evas_Object * keypad)
2187 {
2188         CALC_FUN_BEG();
2189         char *key_name[] = {
2190                 "item_per", "item_sqr", "item_fac", "item_c", "item_div",
2191                     "item_mul", "item_del",
2192                 "item_sin", "item_cos", "item_tan", "item_num7", "item_num8",
2193                     "item_num9", "item_sub",
2194                 "item_ln", "item_log", "item_1x", "item_num4", "item_num5",
2195                     "item_num6", "item_plus",
2196                 "item_10x", "item_x2", "item_xy", "item_num1", "item_num2",
2197                     "item_num3", "item_brack",
2198                 "item_abs", "item_pi", "item_e", "item_num0", "item_dot",
2199                     "item_neg", "item_eq",
2200         };
2201
2202         Evas_Object *item = NULL;
2203         int key_num = sizeof(key_name) / sizeof(key_name[0]);
2204         int i = 0;
2205
2206         for (i = 0; i < key_num; ++i) {
2207                 item =
2208                     (Evas_Object *) edje_object_part_object_get(keypad,
2209                                                                 key_name[i]);
2210                 if (item != NULL) {
2211                         evas_object_event_callback_add(item, EVAS_CALLBACK_MOUSE_DOWN, _calculator_interp, (void *)keypad);
2212                         if (0 == strcmp(key_name[i], "item_del")) {
2213                                 evas_object_event_callback_add(item,
2214                                                                EVAS_CALLBACK_MOUSE_UP,
2215                                                                __calculator_delelte_up,
2216                                                                (void *)keypad);
2217                         }
2218
2219                 }
2220         }
2221         CALC_FUN_END();
2222 }
2223
2224 /**
2225 * @description
2226 *   The callback of input entry when mouse up.
2227 *
2228 * @param    data        unused
2229 * @param    e           unused
2230 * @param    entry       the input entry
2231 * @param    event_info  unused
2232 * @return   void
2233 */
2234 static void
2235 _calc_view_input_entry_mouseup_cb(void *data, Evas * e, Evas_Object * entry,
2236                                   void *event_info)
2237 {       if (data == NULL) {
2238                 return;
2239         }
2240         /* if entry is showing warning message, then input operation is unavailable, just return*/
2241         struct appdata *ad = (struct appdata *)data;
2242         if (ad->wrong_timer) {
2243                 return;
2244         }
2245         calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for  softkey input and mouse move
2246 }
2247
2248 static void
2249 _calc_view_input_entry_to_str(char *entry_str, char *internal_str, int buf_size)
2250 {
2251         CALC_FUN_BEG();
2252         if (entry_str == NULL) {
2253                 return;
2254         }
2255         strncpy(internal_str, entry_str, buf_size - 1);
2256         /* remove result that behind '='(include '=') */
2257         char *enter = strchr(internal_str, '=');
2258         if (enter != NULL) {
2259                 enter--;
2260                 *enter = '\0';
2261         }
2262         calc_expr_replace_from_special_char(internal_str);
2263         /* remove all ','  and '\n'*/
2264         int i = 0;
2265         int j = 0;
2266         while (internal_str[j] != '\0'){
2267
2268                 if (internal_str[j] == separator_ch || internal_str[j] == '\n'){
2269                         j++;
2270                 } else {
2271                         internal_str[i++] = internal_str[j++];
2272                 }
2273         }
2274         internal_str[i] = '\0';
2275         CALC_FUN_END();
2276 }
2277
2278 #ifdef __i386__
2279 static void
2280 _calc_view_input_entry_keyup_cb(void *data, Evas * e, Evas_Object * entry,
2281                                 void *event_info)
2282 {
2283         CALC_FUN_BEG();
2284         calculator_cursor_pos = calc_view_cursor_get_position(entry);   //for hardkey input
2285         int val = 0;
2286         if (data) {
2287                 Evas_Object *obj = (Evas_Object *) data;
2288                 Evas_Event_Key_Up *evt = (Evas_Event_Key_Up *) event_info;
2289                 if (0 == strcmp(evt->key, "Return")) {
2290                         //calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
2291                         __calculator_op_equal(entry);
2292
2293                 }
2294                 val = _calculator_get_input_item_hd(evt->key, obj);
2295                 switch (val) {
2296                 case OP_PLUS:
2297                 case OP_MINUS:
2298                 case OP_MULTIPLY:
2299                 case OP_DIVIDE:
2300                         __calculator_control_normal_func_clicked(e, ad->input_entry, &calc_op_item[val]);
2301                         break;
2302                 case OP_DOT:
2303                         _calc_btn_dot_clicked(ad->input_entry);
2304                         break;
2305                 case OP_NUM_0:
2306                 case OP_NUM_1:
2307                 case OP_NUM_2:
2308                 case OP_NUM_3:
2309                 case OP_NUM_4:
2310                 case OP_NUM_5:
2311                 case OP_NUM_6:
2312                 case OP_NUM_7:
2313                 case OP_NUM_8:
2314                 case OP_NUM_9:
2315                         __calculator_control_panel_number_button_clicked(e, ad-> input_entry, &calc_op_item[val]);
2316                         break;
2317                 case OP_DELETE:
2318                         calc_expr_input_backspace(calculator_input_str, &calculator_cursor_pos);
2319                         break;
2320                 default:
2321                         break;
2322                 }
2323         }
2324         CALC_FUN_END();
2325 }
2326 #endif
2327
2328 static bool
2329 _calc_view_input_entry_error_include(char *string)
2330 {
2331     int i = 0;
2332     for(; i < ARRAY_SIZE(error_string); i++)
2333         {
2334                 if(!strcmp(string, _(error_string[i]))){
2335                         return TRUE;
2336             }
2337     }
2338     return FALSE;
2339 }
2340
2341 /**
2342 * @description
2343 * The callback of input entry when text changed
2344 *
2345 * @param[in]    data    the appdata
2346 * @param[in]    obj     the input entry
2347 * @param[in]    event_info      unused
2348 * @return       void
2349 */
2350 static void
2351 _calc_view_input_entry_changed_cb(void *data, Evas_Object *obj,
2352                                   void *event_info)
2353 {
2354         CALC_FUN_BEG();
2355         if (data == NULL || obj == NULL) {
2356                 return;
2357         }
2358         struct appdata *ad = (struct appdata *)data;
2359         const char *str = (char *)elm_entry_entry_get(obj);
2360
2361         if (paste_flag) {
2362                 char *entry_tmp = elm_entry_markup_to_utf8(str);
2363                 char *entry_expr= elm_entry_markup_to_utf8(entry_tmp);/*because the string format from clipboard is not correct*/
2364                 char internal_expr[MAX_EXPRESSION_LENGTH] = { 0 };
2365                 char f_number_buf[NUMBER_LENGTH] = { 0 };
2366                 char s_number_buf[NUMBER_LENGTH] = { 0 };
2367                 paste_flag = FALSE;
2368                 _calc_view_input_entry_to_str(entry_expr, internal_expr, MAX_EXPRESSION_LENGTH);
2369                 int index = 0;
2370                 bool char_in =__calculator_string_invalid_char_search(internal_expr, &index);
2371                 __calculator_get_cursor_position_float_string(internal_expr, f_number_buf, calculator_cursor_pos, NULL, NULL);
2372                 int cur_pos = calc_view_cursor_get_position(ad->input_entry);
2373                 __calculator_get_cursor_position_float_string(internal_expr, s_number_buf, cur_pos, NULL, NULL);
2374                 int nCntOp = calc_expr_get_operator_num(internal_expr);
2375
2376                 if ((strlen(f_number_buf) > MAX_NUM_LENGTH) || (strlen(s_number_buf) > MAX_NUM_LENGTH)) {
2377                         __calculator_wrong_format_create(CALC_MSG_MAX_DIGIT);
2378                 } else if (nCntOp >= MAX_OPERATOR_NUM) {
2379                         __calculator_wrong_format_create(CALC_MSG_MAX_OP);
2380                 } else {
2381                         if (char_in) {
2382                                 strncpy(calculator_input_str, internal_expr, index);
2383                                 calculator_cursor_pos = index;
2384                         } else {
2385                                 strncpy(calculator_input_str, internal_expr, sizeof(calculator_input_str) - 1);
2386                                 calculator_cursor_pos = cur_pos;
2387                         }
2388                         _calc_entry_text_set(ad->input_entry, calculator_input_str);
2389                 }
2390
2391                 if (entry_tmp) {
2392                         free(entry_tmp);
2393                         entry_tmp = NULL;
2394                 }
2395                 if (entry_expr) {
2396                         free(entry_expr);
2397                         entry_expr = NULL;
2398                 }
2399         } else {
2400                 if (select_mode) {
2401                         char *entry_expr_s = elm_entry_markup_to_utf8(str);
2402                         char internal_expr_s[MAX_EXPRESSION_LENGTH] = { 0 };
2403                         _calc_view_input_entry_to_str(entry_expr_s, internal_expr_s, MAX_EXPRESSION_LENGTH);
2404                         if(!_calc_view_input_entry_error_include(internal_expr_s)){
2405                                 /*change calculator_input_str, after cut operation*/
2406                                 if(calculator_state == CALCULATOR_CALCULATED){
2407                                         calculator_state = CALCULATOR_OPERAND_INPUT;
2408                                 }
2409                                 strncpy(calculator_input_str, internal_expr_s, MAX_EXPRESSION_LENGTH - 1);
2410                                 calculator_cursor_pos = calc_view_cursor_get_position(obj);
2411                         }
2412                         _calc_entry_text_set(obj, calculator_input_str);
2413                         if (entry_expr_s) {
2414                                 free(entry_expr_s);
2415                                 entry_expr_s = NULL;
2416                         }
2417                 }
2418         }
2419         /*
2420          * Prevent pasting images into entry.
2421          * If a image pasted, "<item absize=... href=...>" will be appended into entry.
2422          */
2423         if (strstr(str, "item") != NULL) {
2424                 int pos = 0;
2425                 char buf[MAX_EXPRESSION_LENGTH] = { 0 };
2426
2427                 while (elm_entry_cursor_prev(obj)) {
2428                         pos++;
2429                 }               /* save cursor position */
2430                 pos -= 1;       /* correct */
2431
2432                 strncpy(buf, str, sizeof(buf));
2433                 char *begin = strstr(buf, "<item");
2434                 if (begin != NULL) {
2435                         char *end = strchr(begin, '>');
2436                         string_remove_at(buf, begin - buf, end - begin + 1);    /* remove "<item...>" */
2437                         elm_entry_entry_set(obj, buf);
2438                 }
2439
2440                 while (pos--) {
2441                         elm_entry_cursor_next(obj);
2442                 }               /* retrieve cursor position */
2443
2444                 calc_view_revise_input_scroller(ad);
2445         }
2446         CALC_FUN_END();
2447 }
2448
2449 static void
2450 _calc_view_input_entry_paste_cb(void *data, Evas_Object * obj, void *event_info)
2451 {
2452         CALC_FUN_BEG();
2453         paste_flag = TRUE;
2454         strncpy(calculator_before_paste_str, calculator_input_str,
2455                 MAX_EXPRESSION_LENGTH - 1);
2456         CALC_FUN_END();
2457 }
2458
2459 static void
2460 _calc_view_input_entry_select_start_cb(void *data, Evas_Object * obj, void *event_info)
2461 {
2462         CALC_FUN_BEG();
2463         select_mode = TRUE;
2464         CALC_FUN_END();
2465 }
2466
2467 static void
2468 _calc_view_input_entry_select_changed_cb(void *data, Evas_Object * obj, void *event_info)
2469 {
2470         CALC_FUN_BEG();
2471         CALC_FUN_END();
2472 }
2473
2474 static void
2475 _calc_view_input_entry_select_cleared_cb(void *data, Evas_Object * obj, void *event_info)
2476 {
2477         CALC_FUN_BEG();
2478         select_mode = FALSE;
2479         CALC_FUN_END();
2480 }
2481
2482
2483 /**
2484 * @description
2485 *   Create an entry for inputing expression.
2486 *
2487 * @param    parent          the entry's parent
2488 * @param    ad              the appdata
2489 * @return   Evas_Object*    the input entry
2490 */
2491 static Evas_Object *_calc_view_create_input_entry(Evas_Object * parent,
2492                                                   struct appdata *ad)
2493 {
2494         CALC_FUN_BEG();
2495         Evas_Object *entry = elm_entry_add(ad->edje);
2496         elm_entry_single_line_set(entry, EINA_FALSE);
2497         elm_entry_editable_set(entry, EINA_TRUE);
2498         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
2499         if (strlen(calculator_input_str) > 0) {
2500                 _calc_entry_text_set(entry, calculator_input_str);
2501         } else {
2502                 elm_entry_entry_set(entry, "");
2503         }
2504         elm_entry_cnp_mode_set(entry, ELM_CNP_MODE_NO_IMAGE);
2505         elm_entry_magnifier_disabled_set(entry, EINA_TRUE);
2506         elm_entry_cursor_end_set(entry);
2507         elm_object_focus_set(entry, EINA_TRUE);
2508     elm_object_style_set(entry, "black");
2509         evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND,
2510                                          EVAS_HINT_EXPAND);
2511         evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
2512
2513         evas_object_event_callback_add(entry, EVAS_CALLBACK_MOUSE_UP,
2514                                        _calc_view_input_entry_mouseup_cb, ad);
2515         evas_object_smart_callback_add(entry, "changed",
2516                                        _calc_view_input_entry_changed_cb, ad);
2517         evas_object_smart_callback_add(entry, "selection,paste",
2518                                        _calc_view_input_entry_paste_cb, ad);
2519         evas_object_smart_callback_add(entry, "selection,start",
2520                                        _calc_view_input_entry_select_start_cb, ad);
2521         evas_object_smart_callback_add(entry, "selection,changed",
2522                                        _calc_view_input_entry_select_changed_cb, ad);
2523         evas_object_smart_callback_add(entry, "selection,cleared",
2524                                        _calc_view_input_entry_select_cleared_cb, ad);
2525 #ifdef __i386__
2526         evas_object_event_callback_add(entry, EVAS_CALLBACK_KEY_UP,
2527                                        _calc_view_input_entry_keyup_cb, ad);
2528         evas_object_smart_callback_del (entry, "changed",  _calc_view_input_entry_changed_cb);
2529 #endif
2530         evas_object_show(entry);
2531         limit_filter_data.max_char_count = 0;
2532         limit_filter_data.max_byte_count = 419 + 20;    //19*21+20//result:20
2533         elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size,
2534                                      &limit_filter_data);
2535         elm_entry_text_style_user_push(entry, "DEFAULT='right_margin=32'");
2536         CALC_FUN_END();
2537         return entry;
2538 }
2539
2540 /**
2541 * @description
2542 *   Create a input scrooler which around the input entry.
2543 *   It can give a input entry a scroller.
2544 *
2545 * @param    parent          the parent of input scroller
2546 * @return   Evas_Object*    the input scroller
2547 * @exception
2548 */
2549 static Evas_Object *_calc_view_create_input_scroller(Evas_Object * parent)
2550 {
2551         CALC_FUN_BEG();
2552         Evas_Object *scroller = elm_scroller_add(parent);
2553         elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
2554         evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
2555                                          EVAS_HINT_EXPAND);
2556         evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL,
2557                                         EVAS_HINT_FILL);
2558
2559         evas_object_show(scroller);
2560         CALC_FUN_END();
2561         return scroller;
2562 }
2563
2564 /**
2565 * @description
2566 * Create the background
2567 *
2568 * @param[in]    parent  background's parent
2569 * @return               when success return background, return NULL oppositely
2570 * @retval       layout  if success, return the background
2571 * @retval       NULL    if create failed or parent is null, return null
2572 * @exception
2573 */
2574 static Evas_Object *__create_bg(Evas_Object *parent)
2575 {
2576         CALC_FUN_BEG();
2577         if (parent == NULL) {
2578                 return NULL;
2579         }
2580         Evas_Object *bg = elm_bg_add(parent);
2581         if (bg == NULL) {
2582                 return NULL;
2583         }
2584         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2585         elm_win_resize_object_add(parent, bg);
2586         evas_object_show(bg);
2587         CALC_FUN_END();
2588         return bg;
2589 }
2590
2591 /**
2592 * @description
2593 * Create the main layout
2594 *
2595 * @param[in]    parent  main layout's parent
2596 * @return               when success return a layout, return NULL oppositely
2597 * @retval       layout  if success, return the main layout
2598 * @retval       NULL    if create failed or parent is null, return null
2599 * @exception
2600 */
2601 static Evas_Object *__calc_view_create_layout_main(Evas_Object *parent)
2602 {
2603         CALC_FUN_BEG();
2604
2605         if (parent == NULL) {
2606                 return NULL;
2607         }
2608
2609         Evas_Object *layout = elm_layout_add(parent);
2610         if (layout == NULL) {
2611                 return NULL;
2612         }
2613
2614         elm_layout_theme_set(layout, "layout", "application", "default");
2615
2616         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND,
2617                                          EVAS_HINT_EXPAND);
2618         elm_object_content_set(parent, layout);
2619
2620         edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator",
2621                                 "elm");
2622         evas_object_show(layout);
2623
2624         CALC_FUN_END();
2625
2626         return layout;
2627 }
2628
2629 void _btn_clicked_cb(void *data, Evas_Object * obj, void *event_info)
2630 {
2631         CALC_FUN_BEG();
2632         Evas_Object *win_main = (Evas_Object *) data;
2633         elm_win_lower(win_main);
2634         CALC_FUN_END();
2635 }
2636
2637 /**
2638 * @description
2639 *   Callback function of "Clear" Button on naviframe
2640 *
2641 * @param    data      the appdata
2642 * @param    obj
2643 * @param    event_info
2644 * @return   void
2645
2646 */
2647 static void
2648 __calc_view_clear_clicked_cb(void *data, Evas_Object *obj, void *event_info)
2649 {
2650         CALC_FUN_BEG();
2651         struct appdata *ad = (struct appdata *)data;
2652         if (ad->more_btn_popup) {
2653                 evas_object_hide(ad->more_btn_popup);
2654                 //ad->more_btn_popup= NULL;
2655         }
2656         elm_entry_entry_set(ad->hist_area, "");
2657         elm_entry_entry_set(ad->input_entry, "");
2658         _calc_view_clear_histroy(ad->hist_area);
2659         /* Set input entry as initial state */
2660         _calc_entry_clear(ad->input_entry);
2661         calculator_state = CALCULATOR_WAITING_INPUT;
2662         CALC_FUN_END();
2663 }
2664
2665 Evas_Object *create_toolbar_more_btn(Evas_Object *parent, Evas_Smart_Cb func, void *data)
2666 {
2667         Evas_Object *btn = elm_button_add(parent);
2668         if (!btn) {
2669                 return NULL;
2670         }
2671         elm_object_style_set(btn, "naviframe/more/default");
2672         if (func) {
2673                 evas_object_smart_callback_add(btn, "clicked", func, data);
2674         }
2675         return btn;
2676 }
2677
2678 static void __gl_ctxpopup_hide_cb(void *data, Evas_Object *obj, void *event_info)
2679 {
2680         evas_object_del(obj);
2681 }
2682
2683 static void __calc_view_create_popup(void *data, Evas_Object *parent)
2684 {
2685         if (data == NULL) {
2686                 return;
2687         }
2688         struct appdata *ad = (struct appdata *)data;
2689         ad->more_btn_popup = elm_ctxpopup_add(parent);
2690         const char *profile = elm_config_profile_get();
2691         if (!strcmp(profile, "mobile")) {
2692                 ad->clear_item = elm_ctxpopup_item_append(ad->more_btn_popup,
2693                         CALC_MSG_CLEAR_HISTTORY, NULL, __calc_view_clear_clicked_cb, ad);
2694         } else if (!strcmp(profile, "desktop")) {
2695                 ad->clear_item = elm_ctxpopup_item_append(ad->more_btn_popup,
2696                         CALC_MSG_CLEAR_HISTTORY,  NULL, __calc_view_clear_clicked_cb, ad);
2697         }
2698
2699         Evas_Object *more_btn = NULL;
2700         more_btn = elm_object_item_part_content_get(ad->navi_it, "toolbar_more_btn");
2701         if (more_btn) {
2702                 int x_position = 0;
2703                 int y_position = 0;
2704                 int w = 0;
2705                 int h = 0;
2706                 evas_object_geometry_get(more_btn, &x_position, &y_position, &w, &h);
2707                 evas_object_move(ad->more_btn_popup, x_position + w/4, y_position+h/2);
2708         }
2709
2710         evas_object_show(ad->more_btn_popup);
2711         evas_object_smart_callback_add(ad->more_btn_popup, "dismissed",  __gl_ctxpopup_hide_cb, data);
2712
2713 }
2714
2715 void __calc_view_create_nf_more_btn_cb(void *data, Evas_Object * obj, void *event_info)
2716 {
2717         struct appdata *ad = (struct appdata *)data;
2718         __calc_view_create_popup(data, ad->nf);
2719 }
2720
2721
2722 /**
2723 * @description
2724 *   Load the Naviframe.
2725 *
2726 * @param    ad      the appdata
2727 * @return   naviframe object
2728
2729 */
2730 static Eina_Bool  __calc_view_create_navigation_layout(struct appdata *ad)
2731 {
2732         CALC_FUN_BEG();
2733         Evas_Object *nf = elm_naviframe_add(ad->layout);
2734         if (nf == NULL) {
2735                 return EINA_FALSE;
2736         }
2737         ad->nf = nf;
2738         if (!ad->back_btn) {
2739                 Evas_Object *back_btn = elm_button_add(nf);
2740                 elm_object_style_set(back_btn, "naviframe/end_btn/default");
2741                 evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
2742                 ad->back_btn = back_btn;
2743         }
2744         ad->navi_it = elm_naviframe_item_push(nf, NULL, ad->back_btn, NULL, ad->edje, NULL);
2745         elm_naviframe_item_title_visible_set(ad->navi_it, EINA_FALSE);
2746         ad->more_btn = create_toolbar_more_btn(nf, __calc_view_create_nf_more_btn_cb, ad);
2747         elm_object_item_part_content_set(ad->navi_it, "toolbar_more_btn", ad->more_btn);
2748         evas_object_show(nf);
2749         CALC_FUN_END();
2750         return EINA_TRUE;
2751 }
2752
2753 /**
2754 * @description
2755 *   Load the main view of calculator.
2756 *   Create the input entry and keypad.
2757 *
2758 * @param    ad      the appdata
2759 * @return   void
2760 */
2761 void calc_view_load(struct appdata *ad)
2762 {
2763         CALC_FUN_BEG();
2764         if (ad->bg == NULL) {
2765                 ad->bg = __create_bg(ad->win);
2766         }
2767         ad->conform = elm_conformant_add(ad->win);
2768         evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2769         elm_win_resize_object_add(ad->win, ad->conform);
2770         elm_object_style_set(ad->conform, "nokeypad");
2771         evas_object_show(ad->conform);
2772         ad->layout = __calc_view_create_layout_main(ad->conform);
2773         ad->edje = load_edj(ad->layout, LAYOUT_EDJ_NAME, GRP_MAIN);
2774         evas_object_show(ad->edje);
2775         evas_object_name_set(ad->edje, "edje");
2776
2777         if (__calc_view_create_navigation_layout(ad)) {
2778                 elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf);
2779         }
2780
2781         /* inititialize environment variable */
2782         locale = localeconv();
2783         decimal = locale->decimal_point;
2784         separator = locale->thousands_sep;
2785         int len_seq = strlen(separator);
2786         decimal_ch = decimal[0];
2787         separator_ch = separator[0];
2788         if (len_seq == 2 || len_seq == 0) {
2789                 separator_ch = 32;
2790         }
2791
2792         /*init svi */
2793         feedback_initialize();
2794
2795         /* input area */
2796         ad->input_entry = _calc_view_create_input_entry(ad->edje, ad);
2797         ad->input_scroller = _calc_view_create_input_scroller(ad->edje);
2798         elm_object_content_set(ad->input_scroller, ad->input_entry);
2799         edje_object_part_swallow(_EDJ(ad->edje), "input/entry",
2800                                  ad->input_scroller);
2801         CALC_FUN_END();
2802
2803 }
2804
2805 /**
2806 * @description
2807 *   assign global variable  , this will be removed
2808 *
2809 * @param        ad
2810 * @return       void
2811 * @exception
2812 */
2813 void calc_xxx(struct appdata *ap)
2814 {
2815         ad = ap;
2816 }
2817
2818 static Evas_Object* __set_win_icon(struct appdata *ad)
2819 {
2820         /* set window icon*/
2821         Evas_Object *icon = evas_object_image_add(evas_object_evas_get(ad->win));
2822         evas_object_image_file_set(icon, DESKTOP_MODE_ICON, NULL);
2823         elm_win_icon_object_set(ad->win, icon);
2824         return icon;
2825 }
2826
2827 void win_profile_changed_cb(void *data, Evas_Object * obj, void *event_info)
2828 {
2829         CALC_FUN_BEG();
2830         if (data == NULL) {
2831                 return;
2832         }
2833         struct appdata *ad = (struct appdata *)data;
2834         const char *profile = elm_config_profile_get();
2835         if (!strcmp(profile, "desktop")) {
2836                 /*In destktop mode, Hide indicator & hide back button on the naviframe */
2837                 elm_object_item_part_content_set(ad->navi_it, "prev_btn", NULL);
2838                 elm_object_item_part_content_set(ad->navi_it , "toolbar_button1", NULL);
2839                 elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE);
2840
2841                 /* Show window Icon */
2842                 if (!ad->window_icon) {
2843                         ad->window_icon = __set_win_icon(ad);
2844                 }
2845
2846         } else if (!strcmp(profile, "mobile")) {
2847                 /* In mobile phone mode, show indicator and show back button*/
2848                 elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
2849                 Evas_Object *back_btn = elm_button_add(ad->nf);
2850                 elm_object_style_set(back_btn, "naviframe/end_btn/default");
2851                 evas_object_smart_callback_add(back_btn, "clicked", _btn_clicked_cb, ad->win);
2852                 ad->back_btn = back_btn;
2853                 elm_object_item_part_content_set(ad->navi_it, "prev_btn", ad->back_btn);
2854         }
2855         CALC_FUN_END();
2856 }