# ifndef CORD_POSITION_H

/* The representation of CORD_position.  This is private to the	*/
/* implementation, but the ise is known to clients.  Also	*/
/* the implementation of some exported macros relies on it.	*/
/* Don't use anything defined here and not in cord.h.		*/

# define MAX_DEPTH 48
	/* The maximum depth of a balanced cord + 1.		*/
	/* We don't let cords get deeper than MAX_DEPTH.	*/

struct CORD_pe {
    CORD pe_cord;
    size_t pe_start_pos;
};

/* A structure describing an entry on the path from the root 	*/
/* to current position.						*/
typedef struct CORD_pos {
    size_t cur_pos;
    int path_len;
#	define CORD_POS_INVALID (0x55555555)
		/* path_len == INVALID <==> position invalid */
    struct CORD_pe path[MAX_DEPTH + 1];
    	/* path[path_len] is the leaf corresponding to cur_pos	*/
    	/* path[0].pe_cord is the cord we point to.		*/
    const char *cur_leaf;	/* Current leaf, if it is a string.	*/
    size_t cur_start;	/* Start position of cur_leaf	*/
    size_t cur_end;	/* Ending position of cur_leaf	*/
    			/* 0 if leaf is not string.	*/
} CORD_pos[1];

/* Extract the cord from a position:	*/
CORD CORD_pos_to_cord(CORD_pos p);
	
/* Extract the current index from a position:	*/
size_t CORD_pos_to_index(CORD_pos p);
	
/* Fetch the character located at the given position:	*/
char CORD_pos_fetch(register CORD_pos p);
	
/* Initialize the position to refer to the give cord and index.	*/
/* Note that this is the most expensive function on positions:	*/
void CORD_set_pos(CORD_pos p, CORD x, size_t i);
	
/* Advance the position to the next character.	*/
/* P must be initialized and valid.		*/
/* Invalidates p if past end:			*/
void CORD_next(CORD_pos p);

/* Move the position to the preceding character.	*/
/* P must be initialized and valid.			*/
/* Invalidates p if past beginning:			*/
void CORD_next(CORD_pos p);
	
/* Is the position valid, i.e. inside the cord?		*/
int CORD_pos_valid(CORD_pos p);

 
#define CORD_pos_fetch(p)	\
    (((p)[0].cur_start <= (p)[0].cur_pos && (p)[0].cur_pos < (p)[0].cur_end)? \
     	(p)[0].cur_leaf[(p)[0].cur_pos - (p)[0].cur_start] \
     	: CORD__pos_fetch(p))

#define CORD_next(p)	\
    (((p)[0].cur_pos < (p)[0].cur_end - 1)? \
    	((p)[0].cur_pos++, 1) \
    	: CORD__next(p))

#define CORD_prev(p)	\
    (((p)[0].cur_end != 0 && (p)[0].cur_pos > (p)[0].cur_start)? \
    	((p)[0].cur_pos--, 1) \
    	: CORD__next(p))

#define CORD_pos_to_index(p) ((p)[0].cur_pos)

#define CORD_pos_to_cord(p) ((p)[0].path[0].pe_cord)

#define CORD_pos_valid(p) ((p)[0].path_len != CORD_POS_INVALID)

#endif
