1 /*
2  * AiksaurusGTK - A GTK interface to the AikSaurus library
3  * Copyright (C) 2001 by Jared Davis
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18  * 02111-1307, USA.
19  */
20 
21 #include "AiksaurusGTK_history.h"
22 #include "AiksaurusGTK_strlist.h"
23 #include "AiksaurusGTK_utils.h"
24 
25 #include <cassert>
26 
27 #ifndef NDEBUG
28 	#include <iostream>
29 	using namespace std;
30 #endif
31 
32 //////////////////////////////////////////////////////////////////////////
33 //                                                                      //
34 //   Creation and Destruction                                           //
35 //                                                                      //
36 //////////////////////////////////////////////////////////////////////////
37 
AiksaurusGTK_history()38 AiksaurusGTK_history::AiksaurusGTK_history()
39 {
40 	d_forward_tip_ptr = d_back_tip_ptr = d_current_ptr = static_cast<char*>(NULL);
41 }
42 
43 
~AiksaurusGTK_history()44 AiksaurusGTK_history::~AiksaurusGTK_history()
45 {
46 	if (d_current_ptr)
47 		delete[] d_current_ptr;
48 
49 	if (d_forward_tip_ptr)
50 		delete[] d_forward_tip_ptr;
51 
52 	if (d_back_tip_ptr)
53 		delete[] d_back_tip_ptr;
54 }
55 
56 
57 const char*
tip_forward() const58 AiksaurusGTK_history::tip_forward() const
59 {
60 	static const char* forward = "Forward";
61 	static const char* forwardto = "Forward to ";
62 
63 	const char* nextone = d_forward.look_front();
64 
65 	if (!nextone)
66 	{
67 		return forward;
68 	}
69 
70 	if (d_forward_tip_ptr)
71 		delete[] d_forward_tip_ptr;
72 
73 	d_forward_tip_ptr = AiksaurusGTK_strConcat(forwardto, nextone);
74 
75 	return d_forward_tip_ptr;
76 }
77 
78 const char*
tip_back() const79 AiksaurusGTK_history::tip_back() const
80 {
81 	static const char* back = "Back";
82 	static const char* backto = "Back to ";
83 
84 	const char* backone = d_back.look_front();
85 
86 	if (!backone)
87 	{
88 		return back;
89 	}
90 
91 	if (d_back_tip_ptr)
92 	{
93 		delete[] d_back_tip_ptr;
94 		d_back_tip_ptr = 0;
95 	}
96 
97 	d_back_tip_ptr = AiksaurusGTK_strConcat(backto, backone);
98 
99 	return d_back_tip_ptr;
100 }
101 
102 
103 void
search(const char * str)104 AiksaurusGTK_history::search(const char* str)
105 {
106 	// eliminate all entries which are in forward.
107 	d_forward.clear();
108 
109 	// push current entry to top of back.
110 	if (d_current_ptr != NULL)
111 	{
112 		d_back.push_front(d_current_ptr);
113 		delete[] d_current_ptr;
114 	}
115 
116 	// make current element mirror str.
117 	d_current_ptr = AiksaurusGTK_strCopy(str);
118 }
119 
120 
121 void
move_back()122 AiksaurusGTK_history::move_back()
123 {
124 	// make sure there is something to go back to before continuing.
125 	if (!d_back.size())
126 		return;
127 
128 	// make current element become first element of forward.
129 	d_forward.push_front(d_current_ptr);
130 
131     while (d_forward.size() > 200)
132         d_forward.pop_back();
133 
134 	// make first element of back become current.
135 	delete[] d_current_ptr;
136 	d_current_ptr = AiksaurusGTK_strCopy(d_back.look_front());
137 
138 	// pop first element of back
139 	d_back.pop_front();
140 }
141 
142 
143 void
move_forward()144 AiksaurusGTK_history::move_forward()
145 {
146 	// make sure there is something to move forward to.
147 	if (!d_forward.size())
148 		return;
149 
150 	// make current element become first element of back.
151 	d_back.push_front(d_current_ptr);
152 
153     while (d_back.size() > 200)
154         d_back.pop_back();
155 
156 	// make first element of forward become current.
157 	delete[] d_current_ptr;
158 	d_current_ptr = AiksaurusGTK_strCopy(d_forward.look_front());
159 
160 	// pop first element of forward.
161 	d_forward.pop_front();
162 }
163 
164 
165 void
move_back_to(GList * element)166 AiksaurusGTK_history::move_back_to(GList* element)
167 {
168     int back_steps = 0;
169     for(GList* itor = const_cast<GList*>(d_back.list()); itor != NULL; itor = itor->next)
170     {
171         ++back_steps;
172 
173         if (itor == element)
174         {
175             for(int i = 0;i < back_steps;++i)
176                 move_back();
177 
178             return;
179         }
180     }
181 
182     #ifndef NDEBUG
183     cout << "AiksaurusGTK_history::move_back_to(" << element << ")\n"
184          << "Warning: element is not in back list, and it should be.\n";
185     debug();
186     #endif // NDEBUG
187 }
188 
189 
190 void
move_forward_to(GList * element)191 AiksaurusGTK_history::move_forward_to(GList* element)
192 {
193     int forward_steps = 0;
194     for(GList* itor = const_cast<GList*>(d_forward.list()); itor != NULL; itor = itor->next)
195     {
196         ++forward_steps;
197 
198         if (itor == element)
199         {
200             for(int i = 0;i < forward_steps;++i)
201                 move_forward();
202 
203             return;
204         }
205     }
206 
207     #ifndef NDEBUG
208     cout << "AiksaurusGTK_history::move_forward_to(" << element << ")\n"
209          << "Warning: element is not in forward list, and it should be.\n";
210     debug();
211     #endif // NDEBUG
212 }
213 
214 
215 unsigned int
size_back() const216 AiksaurusGTK_history::size_back() const
217 {
218 	return d_back.size();
219 }
220 
221 
222 unsigned int
size_forward() const223 AiksaurusGTK_history::size_forward() const
224 {
225 	return d_forward.size();
226 }
227 
228 
229 const char*
current() const230 AiksaurusGTK_history::current() const
231 {
232 	return d_current_ptr;
233 }
234 
235 
236 const AiksaurusGTK_strlist&
list_back() const237 AiksaurusGTK_history::list_back() const
238 {
239 	return d_back;
240 }
241 
242 
243 const AiksaurusGTK_strlist&
list_forward() const244 AiksaurusGTK_history::list_forward() const
245 {
246 	return d_forward;
247 }
248 
249 
250 
251 
252 
253 
254 
255 
256 
257 
258 #ifndef NDEBUG
debug()259 void AiksaurusGTK_history::debug()
260 {
261     cout << "History Debug Information ======================" << endl;
262 	cout << tip_back() << "      " << tip_forward() << endl;
263 	cout << "Current: " << current() << endl;
264 
265 	cout << "Back ";
266 	d_back.debug();
267 
268 	cout << "Forward: ";
269 	d_forward.debug();
270     cout << "================================================" << endl;
271 }
272 #endif
273