stdout.[ch]: Make two functions static.
[paraslash.git] / slider.c
1 /*
2  * Copyright (C) 2004-2006 Andre Noll <maan@systemlinux.org>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file slider.c libzmw-based stream creator for paraslash */
8
9 #include "para.h"
10 #include "zmw/zmw.h"
11 #include "math.h"
12 #include "string.h"
13
14 #define WIDTH 300
15 #define SLIDER_RATIO 6
16 #define VAL_2_SL_VAL(v) (v) * (SLIDER_RATIO - 1.0) / SLIDER_RATIO
17 #define SL_VAL_2_VAL(v) (v) * SLIDER_RATIO / (SLIDER_RATIO - 1.0)
18 #define VAL_2_SCORE(v) (v) > 0.5? 1 / (1.03 - (v)) / (1.03 - (v)) :\
19         - 1 / ((v) + 0.03) / ((v) + 0.03)
20
21 #define RGB(R,G,B) (((R)<<12) + ((G)<<6) + (B))
22
23 #define EPSILON 0.001
24 #define LASTPLAYED_FORMULA(v) \
25         1 / (pow((v), 10) + EPSILON * EPSILON) - 1 / (1 + EPSILON) + EPSILON
26
27 #define NUMPLAYED_FORMULA(v)\
28         10 * (v) + (v) / (1 - (v) * (1 - EPSILON))
29
30 static int argc;
31 static char **argv;
32 char *streamname = NULL;
33 static Zmw_Float_0_1 *slider_vals, lastplayed_val, numplayed_val;
34
35 void para_log(int ll, const char* fmt,...) /* no logging */
36 {
37 }
38
39 static void rst(void)
40 {
41         int i;
42         for (i = 1; argv[i]; i++)
43                 slider_vals[i] = VAL_2_SL_VAL(.5);
44         if (streamname)
45                 free(streamname);
46         streamname = para_strdup("slider");
47         //printf("rst: \n");
48 }
49
50 static char *get_value_filename(void)
51 {
52         char *ret, *home =para_homedir();
53         ret = make_message("%s/.paraslash/slide.values", home);
54         free(home);
55         return ret;
56 }
57
58 static void load(void)
59 {
60         char *tmp;
61         char att[999];
62         FILE *f;
63         int i;
64         Zmw_Float_0_1 val;
65
66         tmp = get_value_filename();
67         f  = fopen(tmp, "r");
68         free(tmp);
69         if (!f)
70                 return;
71         while (fscanf(f, "%900s %g", att, &val) == 2) {
72                 if (!strcmp(att, "lastplayed")) {
73                         lastplayed_val = val;
74                         continue;
75                 }
76                 if (!strcmp(att, "numplayed")) {
77                         numplayed_val = val;
78                         continue;
79                 }
80                 for (i = 1; argv[i]; i++)
81                         if (!strcmp(argv[i], att)) {
82                                 slider_vals[i] = val;
83                                 break;
84                         }
85
86         }
87         fclose(f);
88 }
89
90 static void save(void)
91 {
92         char *filename;
93         FILE *f;
94         int i;
95
96         filename = get_value_filename();
97         f  = fopen(filename, "w");
98         free(filename);
99         if (!f)
100                 return;
101         fprintf(f, "lastplayed %g\n", lastplayed_val);
102         fprintf(f, "numplayed %g\n", numplayed_val);
103         for (i = 1; argv[i]; i++)
104                 fprintf(f, "%s %g\n", argv[i], slider_vals[i]);
105         fclose(f);
106 }
107
108
109 static void print_score(FILE *fd)
110 {
111         int i;
112
113         for (i = 1; argv[i]; i++) {
114                 if (SL_VAL_2_VAL(slider_vals[i]) > .99)
115                         fprintf(fd, "deny: IS_N_SET(%s)\n", argv[i]);
116                 if (slider_vals[i] < .01)
117                         fprintf(fd, "deny: IS_SET(%s)\n", argv[i]);
118         }
119         fprintf(fd, "score: 0 ");
120         for (i = 1; argv[i]; i++) {
121                 if (slider_vals[i] < .01)
122                         continue;
123                 fprintf(fd, "+ %i * IS_SET(%s) ",
124                         (int) (VAL_2_SCORE(SL_VAL_2_VAL(slider_vals[i]))),
125                         argv[i]
126                 );
127         }
128         fprintf(fd, " + round((LASTPLAYED()/1440 - 1000 / (LASTPLAYED()/1440 + 1)) / %f"
129                         " - %f * NUMPLAYED(), 2)\n",
130                 LASTPLAYED_FORMULA(SL_VAL_2_VAL(lastplayed_val)),
131                 NUMPLAYED_FORMULA(SL_VAL_2_VAL(numplayed_val)));
132 }
133
134 static void stradd(void)
135 {
136         FILE *pipe;
137         char *cmd = make_message("para_client stradd %s", streamname);
138
139         pipe = popen(cmd, "w");
140         free(cmd);
141         if (!pipe)
142                 return;
143         print_score(pipe);
144         pclose(pipe);
145 }
146
147 static void b_save(void)
148 {
149         stradd();
150         save();
151 }
152
153 static void go(void)
154 {
155         stradd();
156         system("para_client cs slider");
157         system("para_client stop");
158         system("para_client play");
159 }
160
161 static void ok()
162 {
163         stradd();
164         system("para_client cs slider");
165         system("para_client play");
166         save();
167         zmw_main_quit(EXIT_SUCCESS);
168 }
169
170 static void make_buttons(void)
171 {
172         /* Add a frame around the box */
173         ZMW(zmw_decorator(Zmw_Decorator_Border_Embossed)) {
174                 /* the buttons */
175                 ZMW(zmw_hbox()) {
176                         zmw_button("save");
177                         if (zmw_activated())
178                                 b_save();
179                         zmw_button("ok");
180                         if (zmw_activated())
181                                 ok();
182                         zmw_button("go!");
183                         if (zmw_activated())
184                                 go();
185                         zmw_button("rst");
186                         if (zmw_activated())
187                                 rst();
188 //                      zmw_x(WIDTH);
189                         zmw_button("abort");
190                         if (zmw_activated())
191                                 zmw_main_quit(EXIT_FAILURE);
192                 }
193         }
194 }
195 static void make_stream_input_field(void)
196 {
197         static char *text1 = NULL;
198         static int cursor_pos = 1; // Must be static
199         static int text1_length ;
200
201         ZMW(zmw_vbox()) {
202                 if ( text1 == NULL ) {
203                         // The initial value must be malloced
204                         text1 = strdup("slider") ;
205                         text1_length = strlen(text1) ;
206                 }
207                 ZMW(zmw_fixed()) {
208                         zmw_y(6);
209                         zmw_x(0);
210                         zmw_label("stream: ");
211                         zmw_color(Zmw_Color_Foreground, RGB(63, 63, 63));
212                         zmw_y(0);
213                         zmw_x(100);
214                         zmw_width(WIDTH);
215                         zmw_entry_with_cursor(&streamname, &cursor_pos);
216                         if (zmw_changed())
217                                 text1_length = strlen(text1);
218                 }
219         }
220 }
221
222 /* the sliders, one for each member in argv */
223 static void make_sliders(void)
224 {
225         int i;
226         char *txt;
227
228         zmw_height(ZMW_VALUE_UNDEFINED);
229 //                zmw_horizontal_expand(Zmw_True);
230         ZMW(zmw_hbox()) {
231                 ZMW(zmw_vbox()) {
232                         zmw_color(Zmw_Color_Foreground, RGB(0, 63, 63)); /* font */
233                         txt = make_message("lp: (%i%%)",
234                                 (int)(.5 + 100 * SL_VAL_2_VAL(lastplayed_val)));
235                         zmw_label(txt);
236                         free(txt);
237                         txt = make_message("np: (%i%%)",
238                                 (int)(.5 + 100 * SL_VAL_2_VAL(numplayed_val)));
239                         zmw_label(txt);
240                         free(txt);
241                         zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
242                         for (i = 1; argv[i]; i++) {
243                                 txt = make_message("%s: (%i%%)", argv[i],
244                                         (int)(.5 + 100 * SL_VAL_2_VAL(slider_vals[i])));
245                                 zmw_label(txt);
246                                 free(txt);
247                         }
248                 }
249                 ZMW(zmw_vbox()) {
250                         zmw_width(200) ;
251                         zmw_hscrollbar(&lastplayed_val, 1.0 / SLIDER_RATIO);
252                         zmw_hscrollbar(&numplayed_val, 1.0 / SLIDER_RATIO);
253                         for (i = 1; argv[i]; i++) {
254                                 zmw_hscrollbar(&slider_vals[i],
255                                         1.0 / SLIDER_RATIO);
256                         }
257                 }
258         }
259 }
260
261 static void anchor(void)
262 {
263
264         zmw_font_family("terminal");
265         zmw_font_size(14);
266         zmw_rgb(0.1, 0.1, 0.1);
267         zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
268         zmw_color(Zmw_Color_Background_Pushed, RGB(0, 10, 4)); /* slider bg */
269         zmw_color(Zmw_Color_Background_Poped, RGB(0, 42, 42)); /* button bg */
270         zmw_color(Zmw_Color_Border_Light, RGB(0, 7, 63)); /* slider/button border */
271
272         ZMW(zmw_window("para_slider")) {
273                 ZMW(zmw_vbox()) {
274                         make_buttons();
275                         make_stream_input_field();
276                         zmw_color(Zmw_Color_Foreground, RGB(0, 63, 63)); /* font */
277 //                      make_special_sliders();
278                         zmw_color(Zmw_Color_Foreground, RGB(63, 63, 0)); /* font */
279                         make_sliders();
280                 }
281         }
282 }
283
284 static void get_atts(void)
285 {
286         char buf[256];
287         FILE *p = popen("para_client laa", "r");
288         argv = para_malloc(255 * sizeof(char *)); /* FIXME */
289
290         argv[0] = para_strdup("all_attributes");
291         argc = 1;
292         if (!p)
293                 goto err_out;
294         while (fgets(buf, 255, p)) {
295                 chop(buf);
296                 argv[argc] = para_strdup(buf);
297                 argc++;
298         }
299         pclose(p);
300         argv[argc] = NULL;
301         argc--;
302         if (argc > 1)
303                 return; /* success */
304 err_out:
305         if (argc > 1)
306                 for (argc = 1; argv[argc]; argc++)
307                         free(argv[argc]);
308         free(argv);
309         argc = 1;
310 }
311
312 int main(int the_argc, char *the_argv[])
313 {
314         argc = the_argc;
315         argv = the_argv;
316         if (argc < 2) {
317                 get_atts();
318                 if (argc < 2)
319                         return -1;
320         }
321         slider_vals = para_malloc((argc + 1) * sizeof(int*));
322         rst();
323         load();
324 //      printf("argc: %d\n", argc);
325 //      for (i = 1; argv[i]; i++)
326 //              printf("argv[%d]: %s\n", i, argv[i]);
327         zmw_init(&argc, &argv);
328         zmw_main(anchor);
329         return 0;
330 }