/******************************************************************************\
*
* File: ColorStock.cpp
* Creation date: January 05, 2004 20:02
* Author: Mel Viso
* 2004
* Purpose: Method implementations of class 'ColorStock'
*
* Modifications: @INSERT_MODIFICATIONS(* )
* June 22, 2004 05:53 Mel Viso
* Update comment header
* January 05, 2004 22:21 Mel Viso
* Updated code of method 'ColorStock'
* January 05, 2004 21:53 Mel Viso
* Added method 'CyclePalette'
* Added member 'm_pLOGPALETTE'
* Added member 'm_offset'
* Updated code of method '~ColorStock'
* Updated code of method 'ColorStock'
* January 05, 2004 20:20 Mel Viso
* Added method 'GetHPal'
* Added member 'm_hPal'
* Updated code of method '~ColorStock'
* Updated code of method 'ColorStock'
* January 05, 2004 20:02 Mel Viso
* Added method 'FindColorEntry'
* Added method 'DestructorInclude'
* Added method 'ConstructorInclude'
* Added method 'ColorFromIndex'
* Added method '~ColorStock'
* Added method 'ColorStock'
* Added relation 'ColorStock <>-->> ColorEntry'
*
*Copyright (C) 2004, Mel Viso
*
*This program is free software; you can redistribute it and/or
*modify it under the terms of the GNU General Public License
*as published by the Free Software Foundation; either version 2
*of the License, or (at your option) any later version.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License (LICENSE.TXT)
*along with this program; if not, write to the Free Software
*Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
\******************************************************************************/
//@START_USER1
//@END_USER1
// Master include file
#include "MandelZoomModel.h"
//@START_USER2
//@END_USER2
// Static members
/*@NOTE_1050
Constructor method.
*/
ColorStock::ColorStock() //@INIT_1050
: m_hPal()
, m_offset(0)
, m_pLOGPALETTE()
{//@CODE_1050
ConstructorInclude();
//Creamos los diferentes colores
double index=0.001;
COLORREF color,oldColor;
bool bSame=false;
color=ColorFromIndex(index);
do{
if(!bSame){
if(FindColorEntry(color))
break;
new ColorEntry(this,color);
oldColor=color;
}
index+=0.001;
color=ColorFromIndex(index);
if(color==oldColor)
bSame=true;
else
bSame=false;
}while(1);
m_pLOGPALETTE = (LOGPALETTE*)malloc(sizeof(LOGPALETTE)+GetColorEntryCount()*sizeof(PALETTEENTRY));
m_pLOGPALETTE->palVersion = 0x300;
m_pLOGPALETTE->palNumEntries = GetColorEntryCount();
ColorEntryIterator iColorEntry(this);
int i=0;
while (++iColorEntry)
{
COLORREF color=iColorEntry->GetColor();
m_pLOGPALETTE->palPalEntry[i].peFlags = PC_RESERVED;
m_pLOGPALETTE->palPalEntry[i].peBlue =((color&0x00ff0000)>>16);
m_pLOGPALETTE->palPalEntry[i].peGreen=((color&0x0000ff00)>>8);
m_pLOGPALETTE->palPalEntry[i].peRed = (color&0x000000ff);
i++;
}
m_hPal = CreatePalette(m_pLOGPALETTE);
}//@CODE_1050
/*@NOTE_1046
Destructor method.
*/
ColorStock::~ColorStock()
{//@CODE_1046
DestructorInclude();
DeleteObject(m_hPal);
free(m_pLOGPALETTE);
}//@CODE_1046
COLORREF ColorStock::ColorFromIndex(double index)
{//@CODE_1126
double r=index*QuadraticIteration::GetCycleRed()/20.0;
double g=index*QuadraticIteration::GetCycleGreen()/20.0;
double b=index*QuadraticIteration::GetCycleBlue()/20.0;
r=6.283184*(r-floor(r));
g=6.283184*(g-floor(g));
b=6.283184*(b-floor(b));
int iR=int(127.5*(1.0-cos(r)));
int iG=int(127.5*(1.0-cos(g)));
int iB=int(127.5*(1.0-cos(b)));
return RGB(iR,iG,iB);
}//@CODE_1126
void ColorStock::CyclePalette(HDC hDC)
{//@CODE_1135
HPALETTE hOld=SelectPalette(hDC,m_hPal,FALSE);
UINT maps=RealizePalette(hDC);
UINT destIndex=0;
UINT origIndex=m_offset%GetColorEntryCount();
{
UINT l1=GetColorEntryCount()-destIndex;
UINT l2=GetColorEntryCount()-origIndex;
UINT l=(l1<l2)?l1:l2;
AnimatePalette(m_hPal,destIndex,l,m_pLOGPALETTE->palPalEntry+origIndex);
destIndex+=l;
origIndex+=l;
}
destIndex%=GetColorEntryCount();
origIndex%=GetColorEntryCount();
{
UINT l1=GetColorEntryCount()-destIndex-1;
UINT l2=GetColorEntryCount()-origIndex-1;
UINT l=(l1<l2)?l1:l2;
AnimatePalette(m_hPal,destIndex,l,m_pLOGPALETTE->palPalEntry+origIndex);
}
m_offset++;
m_offset%=GetColorEntryCount();
SelectPalette(hDC,hOld,TRUE);
}//@CODE_1135
//{{AFX DO NOT EDIT CODE BELOW THIS LINE !!!
/*@NOTE_1047
Method which must be called first in a constructor.
*/
void ColorStock::ConstructorInclude()
{
// INIT_UNIQUEVALUETREE_OWNED_ACTIVE(ColorStock, ColorStock, ColorEntry, ColorEntry)
_firstColorEntry = (ColorEntry*)0;
_countColorEntry = 0;
}
/*@NOTE_1048
Method which must be called first in a destructor.
*/
void ColorStock::DestructorInclude()
{
// EXIT_UNIQUEVALUETREE_OWNED_ACTIVE(ColorStock, ColorStock, ColorEntry, ColorEntry)
{ for (ColorEntry* item = GetFirstColorEntry(); item; item = GetFirstColorEntry())
delete item; }
}
ColorEntry* ColorStock::FindColorEntry(COLORREF color)
{
// BODY_UNIQUEVALUETREE_FIND(GetColor(), color, ColorStock, ColorStock, ColorEntry, ColorEntry)
ColorEntry* result = 0;
if (_firstColorEntry)
{
ColorEntry* item = _firstColorEntry;
unsigned long bit = 0x1;
while (1)
{
if (item->GetColor() == color)
{
result = item;
break;
}
if ((item->GetColor() & bit) == (color & bit))
{
if (item->_leftColorStock)
{
item = item->_leftColorStock;
}
else
{
break;
}
}
else
{
if (item->_rightColorStock)
{
item = item->_rightColorStock;
}
else
{
break;
}
}
bit <<= 1;
}
}
return result;
}
// Methods for the relation(s) of the class
// METHODS_UNIQUEVALUETREE_OWNED_ACTIVE(GetColor(), ColorStock, ColorStock, ColorEntry, ColorEntry)
void ColorStock::AddColorEntry(ColorEntry* item)
{
assert(this);
assert(item);
assert(item->_refColorStock == (ColorStock*)0);
_countColorEntry++;
item->_refColorStock = this;
if (_firstColorEntry)
{
ColorEntry* current = _firstColorEntry;
unsigned long bit = 0x1;
while (1)
{
assert(current->GetColor() != item->GetColor());
if ((current->GetColor() & bit) == (item->GetColor() & bit))
{
if (current->_leftColorStock)
{
current = current->_leftColorStock;
}
else
{
current->_leftColorStock = item;
item->_parentColorStock = current;
break;
}
}
else
{
if (current->_rightColorStock)
{
current = current->_rightColorStock;
}
else
{
current->_rightColorStock = item;
item->_parentColorStock = current;
break;
}
}
bit <<= 1;
}
}
else
{
_firstColorEntry = item;
}
}
void ColorStock::RemoveColorEntry(ColorEntry* item)
{
assert(this);
assert(item);
assert(item->_refColorStock == this);
ColorStock::ColorEntryIterator::Check(item);
_countColorEntry--;
ColorEntry* replacement = 0;
ColorEntry* move = 0;
if (item->_leftColorStock)
{
replacement = item->_leftColorStock;
replacement->_parentColorStock = item->_parentColorStock;
move = item->_rightColorStock;
}
else if (item->_rightColorStock)
{
replacement = item->_rightColorStock;
replacement->_parentColorStock = item->_parentColorStock;
}
ColorEntry* parent = item->_parentColorStock;
if (parent)
{
if (parent->_leftColorStock == item)
{
parent->_leftColorStock = replacement;
}
else
{
parent->_rightColorStock = replacement;
}
}
else
{
_firstColorEntry = replacement;
}
if (replacement)
{
while (1)
{
ColorEntry* tmp = replacement->_rightColorStock;
replacement->_rightColorStock = move;
if (move)
{
move->_parentColorStock = replacement;
}
if (!replacement->_leftColorStock)
{
if (tmp)
{
replacement->_leftColorStock = tmp;
tmp = 0;
}
else
{
break;
}
}
move = tmp;
replacement = replacement->_leftColorStock;
}
}
item->_refColorStock = (ColorStock*)0;
item->_parentColorStock = (ColorEntry*)0;
item->_leftColorStock = (ColorEntry*)0;
item->_rightColorStock = (ColorEntry*)0;
}
void ColorStock::DeleteAllColorEntry()
{
assert(this);
for (ColorEntry* item = GetFirstColorEntry(); item; item = GetFirstColorEntry())
delete item;
}
void ColorStock::ReplaceColorEntry(ColorEntry* item, ColorEntry* newItem)
{
assert(this);
assert(item);
assert(item->_refColorStock == this);
assert(newItem);
assert(newItem->_refColorStock == (ColorStock*)0);
if (item->GetColor() == newItem->GetColor())
{
ColorStock::ColorEntryIterator::Check(item, newItem);
if (_firstColorEntry == item)
{
_firstColorEntry = newItem;
}
if (item->_parentColorStock)
{
if (item->_parentColorStock->_leftColorStock == item)
{
item->_parentColorStock->_leftColorStock = newItem;
}
else if (item->_parentColorStock->_rightColorStock == item)
{
item->_parentColorStock->_rightColorStock = newItem;
}
}
newItem->_refColorStock = this;
newItem->_parentColorStock = item->_parentColorStock;
newItem->_leftColorStock = item->_leftColorStock;
newItem->_rightColorStock = item->_rightColorStock;
item->_refColorStock = (ColorStock*)0;
item->_parentColorStock = (ColorEntry*)0;
item->_leftColorStock = (ColorEntry*)0;
item->_rightColorStock = (ColorEntry*)0;
}
else
{
ColorStock::ColorEntryIterator::Check(item);
RemoveColorEntry(item);
AddColorEntry(newItem);
}
}
ColorEntry* ColorStock::GetFirstColorEntry() const
{
assert(this);
return _firstColorEntry;
}
ColorEntry* ColorStock::GetLastColorEntry() const
{
assert(this);
ColorEntry* result = _firstColorEntry;
while (result)
{
while (result->_rightColorStock)
{
result = result->_rightColorStock;
}
if (result->_leftColorStock)
{
result = result->_leftColorStock;
}
else
{
break;
}
}
return result;
}
ColorEntry* ColorStock::GetNextColorEntry(ColorEntry* pos) const
{
assert(this);
ColorEntry* result = 0;
if (pos == (ColorEntry*)0)
result = _firstColorEntry;
else
{
assert(pos->_refColorStock == this);
if (pos->_leftColorStock)
{
result = pos->_leftColorStock;
}
else
{
if (pos->_rightColorStock)
{
result = pos->_rightColorStock;
}
else
{
ColorEntry* parent = pos->_parentColorStock;
while (parent && (parent->_rightColorStock == 0 || parent->_rightColorStock == pos))
{
pos = parent;
parent = parent->_parentColorStock;
}
if (parent)
{
result = parent->_rightColorStock;
}
}
}
}
return result;
}
ColorEntry* ColorStock::GetPrevColorEntry(ColorEntry* pos) const
{
assert(this);
ColorEntry* result = 0;
if (pos == (ColorEntry*)0)
result = GetLastColorEntry();
else
{
assert(pos->_refColorStock == this);
if (pos->_parentColorStock)
{
if (pos->_parentColorStock->_leftColorStock == pos || pos->_parentColorStock->_leftColorStock == 0)
{
result = pos->_parentColorStock;
}
else /* Right branche and valid left branche */
{
result = pos->_parentColorStock->_leftColorStock;
while (1)
{
while (result->_rightColorStock)
{
result = result->_rightColorStock;
}
if (result->_leftColorStock)
{
result = result->_leftColorStock;
}
else
{
break;
}
}
}
}
}
return result;
}
int ColorStock::GetColorEntryCount() const
{
assert(this);
return _countColorEntry;
}
// METHODS_ITERATOR_MULTI_ACTIVE(ColorStock, ColorStock, ColorEntry, ColorEntry)
ColorStock::ColorEntryIterator* ColorStock::ColorEntryIterator::_first = 0;
ColorStock::ColorEntryIterator* ColorStock::ColorEntryIterator::_last = 0;
ColorStock::ColorEntryIterator::ColorEntryIterator(
const ColorStock* iterColorStock,
int (ColorEntry::*method)() const,
ColorEntry* refColorEntry)
{
assert(iterColorStock);
_iterColorStock = iterColorStock;
_refColorEntry = _prevColorEntry = _nextColorEntry = refColorEntry;
_prev = (ColorEntryIterator*)0;
_next = (ColorEntryIterator*)0;
_method = method;
if (_last)
{
_last->_next = this;
_prev = _last;
_last = this;
}
else
_first = _last = this;
}
ColorStock::ColorEntryIterator::ColorEntryIterator(
const ColorStock& iterColorStock,
int (ColorEntry::*method)() const,
ColorEntry* refColorEntry)
{
assert(&iterColorStock);
_iterColorStock = &iterColorStock;
_refColorEntry = _prevColorEntry = _nextColorEntry = refColorEntry;
_prev = (ColorEntryIterator*)0;
_next = (ColorEntryIterator*)0;
_method = method;
if (_last)
{
_last->_next = this;
_prev = _last;
_last = this;
}
else
_first = _last = this;
}
ColorStock::ColorEntryIterator::ColorEntryIterator(
const ColorEntryIterator& iterator__,
int (ColorEntry::*method)() const)
{
_iterColorStock = iterator__._iterColorStock;
_refColorEntry = iterator__._refColorEntry;
_prevColorEntry = iterator__._prevColorEntry;
_nextColorEntry = iterator__._nextColorEntry;
_prev = (ColorEntryIterator*)0;
_next = (ColorEntryIterator*)0;
_method = method;
if (_last)
{
_last->_next = this;
_prev = _last;
_last = this;
}
else
_first = _last = this;
}
ColorStock::ColorEntryIterator::~ColorEntryIterator()
{
if (_next)
_next->_prev = _prev;
else
_last = _prev;
if (_prev)
_prev->_next = _next;
else
_first = _next;
}
void ColorStock::ColorEntryIterator::Check(ColorEntry* itemColorEntry)
{
for (ColorEntryIterator* item = _first; item; item = item->_next)
{
if (item->_prevColorEntry == itemColorEntry)
{
item->_prevColorEntry = item->_iterColorStock->GetNextColorEntry(item->_prevColorEntry);
item->_refColorEntry = 0;
}
if (item->_nextColorEntry == itemColorEntry)
{
item->_nextColorEntry = item->_iterColorStock->GetPrevColorEntry(item->_nextColorEntry);
item->_refColorEntry = 0;
}
}
}
void ColorStock::ColorEntryIterator::Check(ColorEntry* itemColorEntry, ColorEntry* newItemColorEntry)
{
for (ColorEntryIterator* item = _first; item; item = item->_next)
{
if (item->_refColorEntry == itemColorEntry)
{
item->_refColorEntry = item->_prevColorEntry = item->_nextColorEntry = newItemColorEntry;
}
if (item->_prevColorEntry == itemColorEntry)
{
item->_prevColorEntry = newItemColorEntry;
item->_refColorEntry = 0;
}
if (item->_nextColorEntry == itemColorEntry)
{
item->_nextColorEntry = newItemColorEntry;
item->_refColorEntry = 0;
}
}
}
//}}AFX DO NOT EDIT CODE ABOVE THIS LINE !!!
//@START_USER3